Func <string,string>和delegate有什么区别?

Die*_*xel 68 c# asp.net lambda delegates

我看到代表有两种形式:

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value);
Run Code Online (Sandbox Code Playgroud)

我不确定这两者之间究竟有什么区别.他们都是代表吗?我相信第一个会使用lambda,第二个必须有一个方法来实际执行工作.我也可能感到困惑.

Jam*_*are 63

首先,你的两个例子是两个完全不同的东西.第一个是声明一个通用委托变量并为其赋值,第二个是定义一个delegate类型.更完整的例子是:

public static class Program
{
    // you can define your own delegate for a nice meaningful name, but the
    // generic delegates (Func, Action, Predicate) are all defined already
    public delegate string ConvertedMethod(string value);

    public static void Main()
    {
        // both work fine for taking methods, lambdas, etc.
        Func<string, string> convertedMethod = s => s + ", Hello!";
        ConvertedMethod convertedMethod2 = s => s + ", Hello!";
    }
}
Run Code Online (Sandbox Code Playgroud)

但更重要的是,双方Func<string,string>delegate string convertMethod(string)就能够保持同样的方法定义,无论是方法,匿名方法或lambda表达式.

至于你应该使用哪种,取决于具体情况.如果您希望通过所需和返回来更多地定义您的委托,那么通用委托就是完美的.如果你想委托有给出该委托应该做的更清晰一些特殊的名字(超越了简单的Action,Predicate等),然后创建自己的代表始终是一个选择.

  • 我认为值得注意的是,Func 和 Action 是代表。当你知道这一点时,这似乎是显而易见的,但在我查看 Func 的签名之前,我对这个事实感到害怕。所以当你说:“首先,你的两个例子正在做两件完全不同的事情。” 你也可以说:“Func 是一个委托”。 (12认同)
  • 一个更清楚的例子是`Func&lt;int, string&gt;`,它表明形式是`Func&lt;arg1, result&gt;`。 (2认同)

Jar*_*Par 12

您拥有的代码示例让人感到困惑,所以让我尝试清除它.以下2项是代表声明.这些很容易被发现,因为它们总是包含delegate关键字

public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);
Run Code Online (Sandbox Code Playgroud)

这行代码将值分配给键入委托的本地

Func<string, string> local = lambda;
Run Code Online (Sandbox Code Playgroud)

上面的代码不仅限于使用lambdas.该值也可以是兼容的方法组或另一个委托值.

另外需要注意的一点是,尽管Func<string, string>并且convertMethod两个代表都具有相同的签名,但它们的值不能相互转换.例如,以下是非法的

Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!
Run Code Online (Sandbox Code Playgroud)


小智 8

来自MSDN,

在2.0之前的C#版本中,声明委托的唯一方法是使用命名方法.C#2.0引入了匿名方法,在C#3.0及更高版本中,lambda表达式取代了匿名方法作为编写内联代码的首选方法.

有一种情况是匿名方法提供lambda表达式中找不到的功能.匿名方法使您可以省略参数列表.这意味着可以将匿名方法转换为具有各种签名的委托.

您可能也对委托关键字vs lambda表达式的这个答案感兴趣.

另外,MSDN上有一篇关于Lambda表达式好文章:

delegate int del(int i);
static void Main(string[] args)
{
    del myDelegate = x => x * x;
    int j = myDelegate(5); //j = 25
}
Run Code Online (Sandbox Code Playgroud)

在前面的示例中,请注意委托签名具有一个类型为int的隐式类型输入参数,并返回一个int.lambda表达式可以转换为该类型的委托,因为它还有一个输入参数(x)和一个返回值,编译器可以隐式转换为int类型.(类型推断将在以下各节中详细讨论.)当使用输入参数5调用委托时,它返回结果25.


fpa*_*is2 5

一个初始化一个委托的实例(可以立即调用)。它是Func <string,string>类型的变量。

B指定委托的定义(其签名)。以后可以使用它定义convertMethod类型的变量。