我不明白这种情况:
public delegate int test(int i);
public test Success()
{
Func<int, int> f = x => x;
return f.Invoke; // <- code successfully compiled
}
public test Fail()
{
Func<int, int> f = x => x;
return f; // <- code doesn't compile
}
为什么我使用
Invoke
时编译正常方法,当我返回 csharp Func<int,int>
时不行直接地?
最佳答案
要理解这种行为,您需要了解两件事。
System.Delegate
,但不同的委托(delegate)有不同的类型,因此不能相互分配。 因为不同的委托(delegate)具有不同的类型,这意味着您不能将一种类型的委托(delegate)分配给另一种类型。
例如,给定:
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.
上面的第一行编译正常,因为它使用特殊处理将 lambda 或方法分配给委托(delegate)。
事实上,这行代码被编译器有效地重写为:
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.
这解释了为什么不能将一种委托(delegate)类型分配给另一种。这只是普通的 C# 语言。
但是,关键是要了解为什么允许将方法或 lambda 分配给兼容的委托(delegate)。如上所述,这是对委托(delegate)的 C# 语言支持的一部分。
所以最后回答你的问题:
当您使用
Invoke()
您正在使用特殊的 C# 语言处理将方法调用分配给委托(delegate),以将方法或 lambda 分配给委托(delegate),而不是尝试分配不兼容的类型 - 因此它可以编译。为了完全清楚,在您的 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
}
关于c# - 为什么当我使用 Invoke 方法时编译正常,而当我直接返回 Func<int,int> 时编译不正常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60597773/