c# - 为什么当我使用 Invoke 方法时编译正常,而当我直接返回 Func<int,int> 时编译不正常?

标签 c# lambda delegates

我不明白这种情况:

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> 时不行直接地?

最佳答案

要理解这种行为,您需要了解两件事。

  • 所有委托(delegate)都来自 System.Delegate ,但不同的委托(delegate)有不同的类型,因此不能相互分配。
  • C#语言provides special handling for assigning a method or lambda to a 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
    {
    }
    

    以下代码将无法编译,即使 Test1Test2派生自同一个基类:
    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/

    相关文章:

    ruby - 将 lambda 存储在通过 switch 语句获取的数组中,然后使用它

    ios - UIImageView 的深层复制没有复制 iOS 中应用于原始 View 的所有委托(delegate)和手势

    c# - 在没有 DTO 类的情况下发布多个参数

    c# - 在 ASP.NET 5 中动态加载程序集

    c# - SQL 连接已打开但未在此处读取

    Java 流 LambdaExp ForEach_

    java - 将多个数组缩减为一个列表

    c# - 当我们在类中或类外定义委托(delegate)时,有什么区别?

    delegates - UITextField,1个字符后自动移至下一个

    c# - 如何查询基于双列为 "close to"某个值的数据集?