using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 델리게이트( delegate 대리자 )
// 함수 자체를 인자로 넘겨주는 기능
// 이벤트 ( event )
// 외부에서 멋대로 호출할 수 있어서 한번 더 매핑해준 것이 event
public class DelegateTest : MonoBehaviour
{
// 반환 : int
// 입력 : void
// 이름 : OnClicked
delegate int OnClicked();
void ButtonPressed(OnClicked clicked) // OnClicked 델리게이트와 반환형, 입력값이 같은 메소드들만 넣어줄 수 있음 !!!
{
clicked();
}
int DeleTest()
{
Debug.Log("DeleTest");
return 0;
}
int DeleTest_Two()
{
Debug.Log("Hello");
return 0;
}
void OnInputKeyTest()
{
Debug.Log("OnInputKeyTest");
}
private void Start()
{
// ========================================================================
// 델리게이트 예시
OnClicked onclick = new OnClicked(DeleTest);
onclick += DeleTest_Two; // 체이닝 ( 차례대로 호출됨 )
onclick(); // 내부적으로 호출
// 델리게이트의 문제점 : 아무데서나 호출됨
// 이에 대응하여
// 이벤트가 생겨남 ( 델리게이트를 한번 더 랩핑해 줌)
// ========================================================================
// 이벤트 예시
InputManager inputManager = new InputManager();
inputManager.InputKey += OnInputKeyTest; // 구독
// 델리게이트와 달리 외부에서 호출하려고 하면 에러 발생 !!!
// inputManager.InputKey();
// 유일하게 할 수 있는건 구독신청해서 실행하는 것
// 이벤트 구독은 외부에서 해줘야하기에 public event ~~ 형식임
// 이벤트 호출은 InputManager 클래스에서만 가능 !!
}
}
익명함수
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 람다식 (lambda)
// 일회용 함수를 만드는데 사용
enum ItemType // 타입
{
Weapon,
Armor,
Amulet,
Ring
}
enum ItemRarity // 등급
{
Rare,
Epic,
Legend
}
class Item
{
public ItemType type;
public ItemRarity rarity;
}
public class LambdaTest : MonoBehaviour
{
List<Item> items = new List<Item>();
delegate bool ItemSelector(Item item); // 반환:bool , 입력:Item class
void Start()
{
items.Add(new Item() { type = ItemType.Weapon, rarity = ItemRarity.Rare });
items.Add(new Item() { type = ItemType.Armor, rarity = ItemRarity.Epic });
items.Add(new Item() { type = ItemType.Amulet, rarity = ItemRarity.Legend });
Item item0 = FindItem(IsWeapon);
// 무명함수, 익명함수 _ 초창기 c# 문법
Item item1 = FindItem( delegate (Item item) { return item.type == ItemType.Weapon; } );
// 람다식 (입력)=>{ 구현 & 반환 }
Item item2 = FindItem( (Item item) => { return item.type == ItemType.Weapon; } );
// 중괄호와 return과 세미콜론 생략
Item item3 = FindItem( (Item item) => item.type == ItemType.Weapon );
// 매개변수의 타입 생략
Item item4 = FindItem( (item) => item.type == ItemType.Weapon );
// 입력변수의 소괄호 생략
Item item5 = FindItem( item => item.type == ItemType.Weapon );
ItemSelector selector = new ItemSelector(item => item.type == ItemType.Weapon);
Item item6 = FindItem(selector);
}
bool IsWeapon(Item item)
{
return item.type == ItemType.Weapon;
}
Item FindItem(ItemSelector select)
{
foreach (var item in items)
{
if (select(item))
{
return item;
}
}
return null;
}
Item FindWeapon()
{
foreach(var item in items)
{
if (item.type == ItemType.Weapon)
{
return item;
}
}
return null;
}
Item FindLegend()
{
foreach (var item in items)
{
if (item.rarity == ItemRarity.Legend)
{
return item;
}
}
return null;
}
}
제네릭 적용
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 람다식 (lambda)
// 일회용 함수를 만드는데 사용
enum ItemType // 타입
{
Weapon,
Armor,
Amulet,
Ring
}
enum ItemRarity // 등급
{
Rare,
Epic,
Legend
}
class Item
{
public ItemType type;
public ItemRarity rarity;
}
public class LambdaTest : MonoBehaviour
{
List<Item> items = new List<Item>();
delegate bool ItemSelector<T>(T item); // 반환:bool , 입력:Item class
delegate R MyFunc<T, R>(T item); // 반환:R(return) , 입력:T(type) // 공용 델리게이트 // 인자 1개
delegate R MyFunc<T1, T2, R>(T1 t1, T2 t2); // 반환:R(return) , 입력:T1 T2(type) // 공용 델리게이트 // 인자 2개
delegate R MyFunc<T1, T2, T3, R>(T1 t1, T2 t2, T3 t3); // 반환:R(return) , 입력:T1 T2 T3(type) // 공용 델리게이트 // 인자 2개
// 위의 코드들은 c#에서 Func이라는 명칭으로 이미 제공해주는 델리게이트들
// Func< ~ >
// Func는 반환값( 제네릭 R )이 있는! 델리게이트
// Action< ~ >
// Action 은 반환값이 없는! 델리게이트
void Start()
{
items.Add(new Item() { type = ItemType.Weapon, rarity = ItemRarity.Rare });
items.Add(new Item() { type = ItemType.Armor, rarity = ItemRarity.Epic });
items.Add(new Item() { type = ItemType.Amulet, rarity = ItemRarity.Legend });
Item item0 = FindItem(IsWeapon);
// 무명함수, 익명함수 _ 초창기 c# 문법
Item item1 = FindItem( delegate (Item item) { return item.type == ItemType.Weapon; } );
// 람다식 (입력)=>{ 구현 & 반환 }
Item item2 = FindItem( (Item item) => { return item.type == ItemType.Weapon; } );
// 중괄호와 return과 세미콜론 생략
Item item3 = FindItem( (Item item) => item.type == ItemType.Weapon );
// 매개변수의 타입 생략
Item item4 = FindItem( (item) => item.type == ItemType.Weapon );
// 입력변수의 소괄호 생략
Item item5 = FindItem( item => item.type == ItemType.Weapon );
ItemSelector<Item> selector = new ItemSelector<Item>(item => item.type == ItemType.Weapon);
Item item6 = FindItem(selector);
}
bool IsWeapon(Item item)
{
return item.type == ItemType.Weapon;
}
//
Item FindItem(ItemSelector<Item> select)
{
foreach (var item in items)
{
if (select(item))
{
return item;
}
}
return null;
}
Item FindItemGeneric(MyFunc<Item, bool> select)
{
foreach (var item in items)
{
if (select(item))
{
return item;
}
}
return null;
}
Item FindItemGeneric(Func<Item, bool> select)
{
foreach (var item in items)
{
if (select(item))
{
return item;
}
}
return null;
}
}
'C#' 카테고리의 다른 글
구조체 메모리 할당 시, 변수 타입의 순서에 주의하기! ( 작은 자료형부터 쓰기 ) (0) | 2023.10.17 |
---|---|
C# 문법 _ 추상클래스, 인터페이스, abstract, virtual (0) | 2023.09.17 |