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

112

我看到委托有两种形式:

A. Func<string, string> convertMethod = lambda 

B. public delegate string convertMethod(string value);

我不确定这两者之间的实际区别。它们都是委托吗?我认为第一个将使用lambda,而第二个将必须有一个方法来执行实际工作。我可能也很困惑。


4个回答

98
首先,你的两个示例正在进行两个完全不同的事情。第一个是声明一个通用的委托变量并给它赋值,第二个只是定义了一个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!";
    }
}

更重要的是,Func<string,string>delegate string convertMethod(string)都能够保存相同的方法定义,无论它们是方法、匿名方法还是Lambda表达式。关于使用哪个取决于具体情况。如果您希望根据委托所需的输入和输出来定义委托,则泛型委托非常适合。如果您想让委托有一些特殊名称,以便更多地定义该委托应执行的操作(超出简单的ActionPredicate等),则始终可以创建自己的委托。


2
一个更清晰的例子是 Func<int, string>,它显示了形式为 Func<arg1, result> - silvalli
23
值得注意的是,Func和Action均为委托。当你知道这一点时,似乎很显然,但在查看Func的签名之前,我对此感到非常困惑。因此,当你说:“首先,你的两个例子正在完成完全不同的事情。” 时,你也可以说:“Func是一个委托”。 - Falk

16

你提供的代码示例有些混乱,让我来试着澄清一下。以下两个是委托声明。这很容易发现,因为它们总是包含delegate关键字。

public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);

这行代码将一个值分配给一个类型为委托的本地变量。

Func<string, string> local = lambda;

上述代码并不仅限于使用lambda表达式。该值也可以是兼容的方法组或另一个委托值。

另一个需要注意的是,尽管Func<string,string>convertMethod都是具有相同签名的委托,但它们的值不能相互转换。例如,以下操作是非法的:

Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!

10

来自 MSDN

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

并且

有一种情况下匿名方法提供了 Lambda 表达式中没有的功能。匿名方法允许省略参数列表。这意味着匿名方法可以转换为具有各种签名的委托。

您可能还对这个关于委托关键字与 Lambda 表达式的回答感兴趣。

此外,MSDN 有一篇关于 Lambda 表达式的好文章

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

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

你也可以从lambda中省略参数。 ()=>Console.Writeline("无参数lambda") - Dr Deo
动作测试 = () =>Console.Writeline("无参lambda表达式"); test.Invoke(); - Dr Deo

7

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接