본문 바로가기
c#

Delegate, Property, nullable, exception, event

by kcj3054 2022. 7. 3.

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