Delegate
- c++의 함수포인터와 비슷한 느낌이다, 인자로 함수 자체를 받아와서 실행을 하는 것. delegate 말 그대로 대리인의 느낌이 존재한다..
- UI 작업을 할 때 어떤 버튼이 눌렸을 때 거기에 연관된 함수가 실행되는 경우가 존재한다. (call back 방식의 느낌)
선언
- delegate int OnClicked();
- 반환은 int이고, OnClicked이 delegate 형식의 이름이다.
예제
class Program
{
delegate int OnClicked();
static void ButtonPressed(OnClicked clickedFunction)
{
clickedFunction();
}
static int TestDelegate()
{
Console.WriteLine("Hello Delegate");
return 0;
}
static int TestDelegate2()
{
Console.WriteLine("Hello Delegate 2");
return 0;
}
static void Main(string[] args)
{
Console.WriteLine();
OnClicked clicked = new OnClicked(TestDelegate);
clicked += TestDelegate2; // chaining이 가능하다 .
ButtonPressed(TestDelegate);
}
}
- clicked += TestDelegate2 처럼 chaining도 가능하다.
- ButtonPressed는 인자로 delegate를 받는다,
- ButtonPressed(TestDelegate);를 보면 TestDelegate를 인자로 넘겨준다, TestDelegate와 OnClicked의 형식이 동일.
Property
nullable
- class처럼 참조타입들은 null체크가 가능한데 int형으로 되어있다면 null이 안되고 숫자로 하거나 해야한다. 그렇지만 int형이라도 null체크가 가능한 문법이 존재한다. int? number = null // int? 문법으로 number변수에 null을 넣을 수 있다.
예제
int? number = null;
int b = number.Value;
///////////////////////////////////
//.Value가 귀찮을 때 한방에 하는 방법
int bbb = number ?? 0; // null이 아니면 number 값을 가지고, 아니면 0을 넣어라.
클래스 null체크
clas Monster
{
pulic int Id{get; set;}
}
Monster monster = null;
if (monster != null)
{
int monsterId = monster.Id;
}
//
int? id = monster?.Id;
- 보통 클래스는 null체크가 가능하다 그렇지만 그것을 더 짧게 하는 방법이 int? id = monster?.Id; 이다 int?형으로 null을 받을 수 있도록하면서 널이면 널 받고 아니면 값 받고..
event
- delegate는 다른쪽에서 접근해서 사용할 수 있다 하지만 delegate를 한번 랩핑한 느낌의 문법이 존재하는데 그것은 event이다.
- unity에서 어떤 클릭을 했을 때 클릭을 InputManager에서 체크하고, 발생할 이벤트들을 뿌려주는 역할한다고 해보자.
InputManager
public class InputManager
{
public delegate void OnInputKey(); //delegate 선언
public event OnInputKey InputKey;
public void Update()
{
if (Console.KeyAvailable == false)
return;
ConsoleKeyInfo info = Console.ReadKey();
if (info.Key == ConsoleKey.A) //키가 눌렸을때
{
// 구독한 모두한테 알려준다. (event 발생) !
InputKey();
}
}
}
main함수 영역
static void OnInputTest()
{
Console.WriteLine("Input Received!");
}
static void Main(string[] agrs)
{
InputManager inputManager = new InputManager();
inputManager.InputKey += OnInputTest; // 유튜브 구독 느김
while (true)
{
inputManager.Update();
}
}
- 이벤트는 유튜브 구독과, 구독자에게 정보 뿌림으로 생각하면된다. 이벤트인 inputManager.InputKey에 += 하는 것은 구독이라고 새악하다.
- a키글 누르면 인풋매니저의 업데이트문에서 InputKey인 event가 발생한다!
- 이벤트 선언은 delegate 앞에 event만 붙여주면된다.
reflection
- reflection은 x -ray를 찍는 것이다. 실시간으로 해당 개체의 정보를 얻어올 수 있다 또한 이러한 기능으로 unity에서 ui쪽에서 실시간으로 script의 코드를 건드릴 수 있다. public int a 로하면 a의 값을 조정가능. private로 하면 불가능 그렇지만 [SerializedField]를 추가하면 private이지만 내가 ui에서 조종가능
LAMBDA
일회용 함수를 사용한다고 생각하자. 람다를 사용해서 함수인자가 델리게이트면 그쪽으로 넘길 수도 있다.
delegate를 직접선언하지 않아도 만들어진 것들이 존재하는데 그것들이 Func<>나 Action이다. 반환 값이 없다면 Action을 사용하면되고, 반환값이 존재한다면 Func<>를 사용하면된다.
기본적인 람다 예제
Func<Item, bool> selector = (Item item) => { return item.ItemType == ItemType.Ring; }; =>오른쪽이 람다 expression // Func<Item, bool>의 의미는 인자는 Item이고, 반환값이 bool인 것이다.
delegate인자 + 람다
static Item FindItem(Func<Item, bool> selector)
{
foreach (Item item in _items)
{
if (selector(item))
{
return item;
}
}
return null; }
static void Main(string[] agrs)
{
_items.Add(new Item() {ItemType = ItemType.Weapon, Rarity = Rarity.Normal});
//delegate를 직접 선언하지 않아도, 이미 만들어진 애들이 존재한다.
// 반환 타입이 있을 경우 Func
// 없을 경우 Action
//Item item = FindItem( (Item item) => { return item.ItemType == ItemType.Ring; });
Func<Item, bool> selector = (Item item) => { return item.ItemType == ItemType.Ring; };
Item item = FindItem((Item item) => { return item.ItemType == ItemType.Ring; });
}
FindItem의 인자가 Func<>로 delegate를 받을 수 있다, FindItem를 호출하면서 람다함수로 인자를 넘기고있다.
출처 : 루키스님의 c#강의를 통해 학습했습니다.
'c#' 카테고리의 다른 글
추상 vs 인터페이스 (0) | 2022.12.05 |
---|---|
c#의 init access 문법과 top level (0) | 2022.07.24 |
Immutable (0) | 2022.07.07 |
MessagePack (0) | 2022.07.06 |
readonly vs const (0) | 2022.07.06 |