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
출처
- https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/delegates/
- https://docs.microsoft.com/ko-kr/dotnet/csharp/programming-guide/concepts/covariance-contravariance/using-variance-in-delegates
- https://mrw0119.tistory.com/19
- https://scvtwo.tistory.com/52
- https://docs.microsoft.com/ko-kr/dotnet/api/system.action-1?view=net-5.0
- https://docs.microsoft.com/ko-kr/dotnet/api/system.func-2?view=net-5.0
- https://www.tutorialsteacher.com/csharp/csharp-covariance-and-contravariance
- http://www.csharpstudy.com/Tip/Tip-Func.aspx