Bu davranışı anlamak için bilmeniz gereken iki şey var.
- Tüm delegeler türetilir
System.Delegate
, ancak farklı delegelerin farklı türleri vardır ve bu nedenle birbirlerine atanamazlar.
- C # dili , bir temsilciye bir yöntem veya lambda atamak için özel işlem sağlar .
Farklı delegelerin farklı türleri olduğundan, bu, bir türden başka bir delege atayamayacağınız anlamına gelir.
Örneğin, verilenler:
delegate void test1(int i);
delegate void test2(int i);
Sonra:
test1 a = Console.WriteLine; // Using special delegate initialisation handling.
test2 b = a; // Using normal assignment, therefore does not compile.
Yukarıdaki ilk satır, bir delege için lambda veya yöntem atamak için özel işlemeyi kullandığından, Tamam derler.
Aslında, bu satır derleyici tarafından etkili bir şekilde yeniden yazılır:
test1 a = new test1(Console.WriteLine);
Yukarıdaki ikinci satır derlenmez, çünkü bir türden bir örneği başka bir uyumsuz türe atamaya çalışmaktadır.
Tiplere göre , farklı tipler olduğu için test1
ve test2
bunlar arasında uyumlu bir atama yoktur .
Düşünmeye yardımcı oluyorsa, bu sınıf hiyerarşisini düşünün:
class Base
{
}
class Test1 : Base
{
}
class Test2 : Base
{
}
Aşağıdaki kod derlemek, olsa ETMEYECEKTIR Test1
ve Test2
aynı temel sınıf türetmek:
Test1 test1 = new Test1();
Test2 test2 = test1; // Compile error.
Bu, neden bir temsilci türünü diğerine atayamayacağınızı açıklar. Bu sadece normal C # dili.
Ancak, önemli olan, uyumlu bir delege için neden bir yöntem veya lambda atamanıza izin verildiğini anlamaktır. Yukarıda belirtildiği gibi, bu delegeler için C # dil desteğinin bir parçasıdır.
Sonunda sorunuzu cevaplamak için:
Kullandığınızda Invoke()
, uyumlu olmayan bir tür atamaya çalışmak yerine bir temsilciye yöntem veya lambdas atamak için özel C # dil işlemeyi kullanarak temsilciye bir METHOD çağrısı ataıyorsunuz - bu nedenle Tamam derliyor.
Tamamen açık olmak gerekirse, OP'nizde derleyen kod:
public test Success()
{
Func<int, int> f = x => x;
return f.Invoke; // <- code successfully compiled
}
Aslında kavramsal olarak şuna dönüştürülür:
public test Success()
{
Func<int, int> f = x => x;
return new test(f.Invoke);
}
Başarısız olan kod iki uyumsuz tür arasında atamaya çalışırken:
public test Fail()
{
Func<int, int> f = x => x;
return f; // Attempting to assign one delegate type to another: Fails
}