delegate 키워드

delegate(대리자) 키워드

  • delegate는 메서드를 다른 메서드에 인수로 전달하는 데 사용
  • 형식이 일치하는 구조의 모든 메서드는 대리자에 할당할 수 있다
  • 메서드는 정적/인스턴스일 수 있다.

delegate 속성

  • 함수 포인터와 유사하지만, 객체 지향적으로 인스턴스 및 메서드를 캡슐화한다.
  • 메서드를 매개 변수로 전달할 수 있다.
  • 콜백 메서드를 정의할 수 있다.
  • callback method 와 generic delegate에 주로 쓰인다.
    • callback method - delegate를 parameter로 받아 실행시키는 method
    • generic delegate - template를 이용해 class T로 일반화 가능하다.
  • operator += 또는 -=로 delegate chain 가능하다.

delegate 가변성 사용

Covariance 공변성

  • 기존에 정의된 반환 타입의 파생 클래스를 반환하는 것을 허용
  • delegate, generic, array, interface 등에 적용 가능
public class Small { }
public class Big: Small { }
public class Bigger : Big { }

public delegate Small covarDel(Big mc);

public class Program
{
    public static Big Method1(Big bg)
    {
        Console.WriteLine("Method1");
    
        return new Big();
    }
    public static Small Method2(Big bg)
    {
        Console.WriteLine("Method2");
    
        return new Small();
    }
        
    public static void Main(string[] args)
    {
        covarDel del = Method1;

        Small sm1 = del(new Big());

        del= Method2;
        Small sm2 = del(new Big());
    }
}

Contravariance 반공변성

  • 메서드가 대리자 형식보다 더 하위로 파생된 매개 변수 형식을 갖도록 허용
  • 부모 클래스를 매개 변수로 사용하는 메서드를, 파생 클래스를 매개 변수로 하는 대리자에 전달 가능
// 파생 클래스를 매개변수로 하는 대리자
delegate Small covarDel(Big mc);

class Program
{
    // 동일한 파생 클래스가 매개변수
    static Big Method1(Big bg)
    {
        Console.WriteLine("Method1");
        return new Big();
    }
    // 동일한 파생 클래스가 매개변수
    static Small Method2(Big bg)
    {
        Console.WriteLine("Method2");
        return new Small();
    }
    // 부모 클래스가 매개변수
    static Small Method3(Small sml)
    {
        Console.WriteLine("Method3");
        
        return new Small();
    }
    
    // Ouptut:
    // Method1
    // Method2
    // Method3
    // 정상적으로 아웃풋 출력
    static void Main(string[] args)
    {
        covarDel del = Method1;
        del += Method2;
        del += Method3;

        Small sm = del(new Big());
    }
}

Covariance와 Contravariance의 동시 적용


// 부모클래스를 반환하고 파생 클래스를 매개변수로 하는 대리자
delegate Small covarDel(Big mc);

class Program
{
    // 파생 클래스를 반환하고 부모 클래스를 매개변수로 하는 함수
    static Big Method4(Small sml)
    {
        Console.WriteLine("Method3");
    
        return new Big();
    }

    // Output:
    // Method4
    // 정상적으로 출력
    // 매개변수에서는 Contravariance,
    // 리턴타입에서는 Covariance 적용
    static void Main(string[] args)
    {
        covarDel del = Method4;
    
        Small sm = del(new Big());
    }
}

Action vs. Func

  Action Func
매개변수 0~16개 가질 수 있음 0~16개 가질 수 있음 / 반환 값은 1개 별도
값 반환 값을 반환하지 않는 메서드를 캡슐화 값을 반환하는 메서드를 캡슐화
내용 Action<T1, T2, …>
- T1, T2, …는 파라미터
- 공통된 파라미터 갯수 및 타입을 공유하는 delegate를 할당할 수 있음
Func<T1, T2, …, R>
- R은 Return Type
- T1, T2, …는 파라미터
- 공통된 Return Type, 파라미터 갯수 및 타입을 공유하는 delegate를 할당할 수 있음

Predicate

  • 반환 값이 무조건 bool
  • 입력 파라미터는 1개
  • Func<T, bool>과 동일하게 표현 가능 (T타입 파라미터 1개와 bool 리턴 타입)
    • Predicate는 .NET 2.0에서 Array 및 List 지원을 위해 추가
    • Func는 .NET 3.5에서 LINQ 등을 지원하기 위해 추가
// Predicate<T>
Predicate<int> p = delegate(int n)
{
   return n >= 0;
};
bool res = p(-1); // false

Predicate<string> p2 = s => s.StartsWith("A");
res = p2("Apple"); // true

출처

Categories: ,

Updated: