경일게임아카데미 멀티 디바이스 메타버스 플랫폼 개발자 양성과정 20220811 2022/04/04~2022/12/14

Jinho Lee·2022년 8월 11일
0

2022.08.11 경일 메타버스 19주차 4일 수업내용. 대리자와 이벤트, 람다식, 추가 - 옵저버 패턴에의 활용

대리자와 이벤트

  • 자료 : 교과서 “이것이 C#이다” ch.13 대리자와 이벤트 p. 455

  • 어제 내용 이어서
    Notion / Velog

익명 메소드 (Anonymous Method)

  • p. 472 ~ 475

  • 이름이 없는 메소드

  • 사용

    1. 대리자를 선언 후, 인스턴스 생성

    2. delegate 키워드를 이용해 메소드의 구현이 담겨 있는 코드 블록을 참조

      ⇒ 여기서 코드 블록이 익명 메소드

    3. 대리자의 인스턴스를 호출하면 익명 메소드 호출

    • 형식

      대리자_인스턴스 = delegate ( 매개변수_목록 )
      								 {
      								 // 실행하고자 하는 코드
      								 };
      
      ex)
      delegate int Calculate( int a, int b );
      
      public static void Main()
      {
      		Calculate Calc;
      
      		Calc = delegate ( int a, int b ) // 익명 메소드
      					 {
      								return a + b;
      					 };
      
      		Console.WriteLine( "3 + 4 : {0}", Calc( 3, 4 ) );
      }
  • 사용하는 이유 :
    대리자가 참조할 메소드를 넘겨야 할 때, 이 메소드가 두 번 다시 사용할 일이 없다고 판단되면 익명 메소드를 활용

이벤트 (Event)

  • p. 476 ~ 479

  • 객체에 일어난 사건 알리기

  • 이벤트의 동작 원리는 대리자와 거의 비슷하다.
    ⇒ 이벤트는 대리자를 event 한정자로 수식해서 만든다.

  • 사용 절차

    1. 대리자 선언

      → 대리자는 클래스의 안과 밖 어디에 위치해도 상관없다.

    2. 클래스 안대리자의 인스턴스event 한정자로 수식해서 선언

    3. 이벤트 핸들러 작성

      → 선언한 대리자와 일치하는 메소드

    4. 대상 객체의 이벤트이벤트 핸들러 등록

    5. 이벤트가 발생하면 이벤트 핸들러 호출

  • 이벤트 활용 예시 코드 : p. 479

    2022. 08. 11 이벤트 활용 예시 코드

대리자와 이벤트의 차이점

  • p. 480 ~ 481

  • 대리자 : public 또는 internal로 수식되어 있으면 클래스 외부에서 호출 가능

  • 이벤트 : public으로 수식되어 있어도 선언된 클래스 외부에서 호출이 불가능

    • 이는 견고한 이벤트 기반 프로그래밍을 가능하게 한다.

    • 포함된 객체만의 상태를 감시할 수 있다.

  • 이러한 차이는 두 가지의 용도를 분리한다.

    • 대리자 ⇒ 콜백 용도

    • 이벤트 ⇒ 객체의 상태 변화 / 사건의 발생을 알리는 용도

람다식 (Lambda Expression)

  • 자료 : 교과서 “이것이 C#이다” ch.14 람다식 p. 485

  • 1936년 수학자 알론조 처치(Alonzo Church)가 발표한 람다 계산법에서 사용하는 식

    • 람다 계산법은 함수의 정의와 변수, 함수의 적용으로 구성

    • 모든 것이 함수로 이루어져있다.

      • ex) 함수를 변수에 대입 → 함수의 적용
  • 주류 프로그래밍 언어는 대부분 람다식을 지원한다.

    • C#은 C# 3.0에서 도입
  • 익명 메소드를 만들기 위해 사용

    • 람다식으로 만드는 익명 메소드
      무명 함수 (Anonymous Function)
  • 형식

    매개변수_목록 => 식
    
    ex)
    delegate int Calculate(int a, int b);
    
    //.
    ..
    static void Main(string[] args)
    {
    		Calculate calc = (int a, int b) => a + b;
    }
    • C# 컴파일러는 “형식 유추(Type Inference)” 기능을 제공하여 코드를 간결히 만든다.

      delegate int Calculate(int a, int b);
      
      //.
      ..
      static void Main(string[] args)
      {
      		Calculate calc = (a, b) => a + b;
      }

문 형식의 람다식

  • p. 490 ~ 491

  • 람다식의 오른편에 식 대신 코드 블록이 온다.

    (매개변수_목록) => {
    						문장1;
    						문장2;
    						문장3;
    				  }
    
    ex)
    delegate void DoSomething();
    
    //.
    ..
    static void Main(string[] args)
    {
    		DoSomething DoIt = () => 
    						{
    							Console.WriteLine("뭔가를");
    							Console.WriteLine("출력해보자");
    							Console.WriteLine("이렇게");
    						};
    
    		DoIt();
    }
  • 문 형식의 람다식을 활용한 예시 코드 ; p. 491 ~ 492

    2022. 08. 11 문 형식의 람다식 활용 예시 코드

Func 대리자, Action 대리자

  • p. 492 ~ 495

  • 별도로 대리자를 선언하지 않아도 사용할 수 있는,
    미리 선언된 대리자

  • Func 대리자는 결과를 반환하는 메소드를 참조

  • Action 대리자는 결과를 반환하지 않는 메소드를 참조

Func 대리자

  • 결과를 반환하는 메소드를 참조

  • 17가지 버전 → 1개의 형식 매개변수 ~ 17개의 형식 매개변수

  • 가장 마지막 형식 매개변수 ⇒ 반환 형식

  • 다음의 예외가 아니면 별도의 대리자를 선언할 필요가 없다.

    1. 입력 매개변수가 16개 이상
    2. ref, out 한정자로 수식된 매개변수 사용

Action 대리자

  • Func 대리자와 흡사하다.

  • 결과를 반환하지 않는 메소드를 참조
    반환 형식 없음

  • 17가지 버전 → 0개 ~ 16개 형식 매개변수
    ⇒ 형식 매개변수가 모두 입력 매개변수

  • 일련의 작업 수행이 목적

추가 자료

https://docs.google.com/document/d/18eUQPpJqRbfC9v1XYP5b9u4H7PDUeIPcW4aOrxD11NE/edit#

  • delegate

    • private delegate void SecondElapsedDelegate();
      // void() 타입의 함수만 보관할 수 있다.
      // delegate타입을 정의한다.

    • 위와 같은 코드 :
      public class SecondElapsedDelegate : System.MulticastDelegate
      {

      }
      // 이처럼 System.MulticastDelegate를 상속받는 것을
      // delegate라는 한정자로 축약한 것

    • 호출 방법

      1. OnSecondElapsed();연결된 메소드를 모두 호출

      2. OnSecondElapsed.Invoke()로 호출(통지)

      1. 대리자 체인에 메소드를 연결할 때, 중복을 방지하기 위해
        항상 먼저 해당 함수의 연결을 끊고 다시 연결하자.

      2. 코루틴외부에 노출시키면 StartCoroutine으로 외부에서 실행해야한다.
        그렇기에 코루틴은 내부로 숨기고 다른 public 함수에 StartCoroutine을 넣어 넘겨주는 편이 좋다.

대리자와 이벤트 추가 정리

대리자

  • 함수를 보관할 수 있는 타입

  • 사용자 정의 대리자를 만들 수도 있지만 System.Action 혹은 System.Func 혹은 Unity에서는 UnityAction을 사용할 수 있다.

  • Invoke() 메소드보관된 모든 함수를 호출할 수 있다.

이벤트

  • 옵저버 패턴을 쉽게 사용하기 위한 타입

  • 선언된 대리자 타입의 함수를 보관할 수 있다.

  • 대리자와 다르게 외부에서 Invoke()를 할 수 없다.

  • 함수가 중복되어 추가 된다면 디버깅이 매우 어렵기 때문에, 꼭 추가 전에는 삭제를 해준다.

  • 이벤트 객체에 아무런 함수도 없는 경우에는 null이기 때문에 Invoke()를 호출할 때는 꼭 Null 체크를 해준다.

    • Ex. OnTakenDamage?.Invoke();
  • 활용 방법은 "Event"의 의미대로 특정 사건(혹은 시점)을 나타내며, 그 시점에 일어나야 하는 일들(코드 상에서는 메소드로 표현)을 일으킬 수 있다.

  • 주의 사항 / 하기 쉬운 실수

    1. 특정 시점이 됐는데 Invoke() 호출을 빼먹은 경우

    2. Invoke() 될 때 실행되어야 할 메소드를 추가하지 않은 경우

객체 지향 설계

  • 객체 지향 설계의 핵심은 메시지다.

  • 메시지 전달을 코드로 표현하려면 메소드를 호출하면 된다.

0개의 댓글