이 동작을 이해하기 위해 알아야 할 두 가지가 있습니다.
- 모든 델리게이트는에서 파생
System.Delegate
되지만 다른 델리게이트는 유형이 다르므로 서로를 할당 할 수 없습니다.
- C # 언어 는 메서드 나 람다를 대리자에게 할당하기위한 특수 처리 기능을 제공합니다 .
다른 델리게이트의 유형이 다르므로 한 유형의 델리게이트를 다른 유형에 지정할 수 없습니다.
예를 들면 다음과 같습니다.
delegate void test1(int i);
delegate void test2(int i);
그때:
test1 a = Console.WriteLine; // Using special delegate initialisation handling.
test2 b = a; // Using normal assignment, therefore does not compile.
위의 첫 번째 줄은 람다 또는 메서드를 대리자에 할당하기 위해 특수 처리를 사용하므로 OK를 컴파일합니다.
실제로이 줄은 컴파일러에 의해 다음과 같이 효과적으로 다시 작성됩니다.
test1 a = new test1(Console.WriteLine);
위의 두 번째 줄은 한 유형의 인스턴스를 다른 호환되지 않는 유형에 할당하려고하기 때문에 컴파일되지 않습니다.
지금까지 유형에 갈 때, 사이의 대입 호환성이없는 test1
및 test2
서로 다른 종류 때문에이.
생각하는 데 도움이된다면이 클래스 계층 구조를 고려하십시오.
class Base
{
}
class Test1 : Base
{
}
class Test2 : Base
{
}
다음 코드는 컴파일, 비록되지 않습니다 Test1
와 Test2
같은 기본 클래스에서 파생 :
Test1 test1 = new Test1();
Test2 test2 = test1; // Compile error.
이것은 한 델리게이트 유형을 다른 델리게이트 유형에 할당 할 수없는 이유를 설명합니다. 그것은 단지 일반적인 C # 언어입니다.
그러나 중요한 것은 왜 메서드 나 람다를 호환 가능한 대리자에게 할당 할 수 있는지 이해하는 것입니다. 위에서 언급했듯이 이는 델리게이트에 대한 C # 언어 지원의 일부입니다.
마지막으로 귀하의 질문에 대답하십시오.
사용할 때 Invoke()
호환되지 않는 형식을 할당하지 않고 메서드 또는 람다를 대리자에 할당하기 위해 특수 C # 언어 처리를 사용하여 대리자에 METHOD 호출을 할당하므로 확인이 컴파일됩니다.
OP에서 컴파일하는 코드는 완전히 명확하게합니다.
public test Success()
{
Func<int, int> f = x => x;
return f.Invoke; // <- code successfully compiled
}
실제로 개념적으로 다음과 같은 것으로 변환됩니다.
public test Success()
{
Func<int, int> f = x => x;
return new test(f.Invoke);
}
실패한 코드는 호환되지 않는 두 가지 유형 사이에 할당하려고 시도합니다.
public test Fail()
{
Func<int, int> f = x => x;
return f; // Attempting to assign one delegate type to another: Fails
}