Func<string,string> 和委托有啥区别?
Posted
技术标签:
【中文标题】Func<string,string> 和委托有啥区别?【英文标题】:What is the difference between Func<string,string> and delegate?Func<string,string> 和委托有什么区别? 【发布时间】:2011-10-12 17:12:33 【问题描述】:我看到代表有两种形式:
A. Func<string, string> convertMethod = lambda
B. public delegate string convertMethod(string value);
我不确定这两者之间的实际区别是什么。他们都是代表吗?我相信第一个会使用 lambda,而第二个必须有一种方法来实际执行工作。我可能也很困惑。
【问题讨论】:
Declare delegate manually, use Func<T> or Action<T>? 的可能重复项 【参考方案1】:首先,您的两个示例正在做两件完全不同的事情。第一个是声明一个通用委托变量并为其分配一个值,第二个只是定义一个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 表达式。
至于应该使用哪个,视情况而定。如果您希望您的委托更多地由它接受和返回的内容来定义,那么通用委托是完美的。如果您希望代理有一些特殊的名称,可以更详细地定义代理应该做什么(除了简单的Action
、Predicate
等),那么创建自己的代理始终是一种选择。
【讨论】:
一个更清晰的例子是Func<int, string>
,它表明表单是Func<arg1, result>
。
我认为值得注意的是 Func 和 Action 是代表。当您知道时,这似乎很明显,但是在查看 Func 的签名之前,我对这个事实感到害怕。所以当你说:“首先,你的两个例子在做两件完全不同的事情。”你也可以说:“Func 是一个代表”。【参考方案2】:
您拥有的代码示例有点令人困惑,所以让我试着把它弄清楚。以下 2 项是委托声明。这些很容易发现,因为它们总是包含 delegate
关键字
public delegate TReturn Func<TArg, TReturn>(Targ value);
public delegate string convertMethod(string value);
这行代码将一个值分配给一个输入到委托的本地
Func<string, string> local = lambda;
上面的代码不仅限于使用 lambdas。该值也可以是兼容的方法组或另一个委托值。
另外需要注意的一点是,尽管Func<string, string>
和convertMethod
都是具有相同签名的委托,但它们的值不可相互转换。例如以下是非法的
Func<string, string> local1 = ...;
convertMethod local2 = local1; // Error!!!
【讨论】:
【参考方案3】:来自MSDN,
在 2.0 之前的 C# 版本中,声明委托的唯一方法是 使用命名方法。 C# 2.0 在 C# 中引入了匿名方法 3.0 及更高版本,lambda 表达式取代匿名方法作为 编写内联代码的首选方式。
和
在一种情况下,匿名方法提供了功能 在 lambda 表达式中找不到。匿名方法使您可以省略 参数列表。这意味着匿名方法可以 转换为具有各种签名的代表。
您可能也对delegate keyword vs lambda expression 上的这个 SO 回答感兴趣。
另外,MSDN 有一个good article on Lambda Expressions:
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") 动作测试 = () =>Console.Writeline("parameter less lambda"); test.Invoke();【参考方案4】:A 初始化委托的一个实例(可以立即调用)。它是一个 Func 类型的变量。
B 指定委托的定义(其签名)。以后可以用它来定义convertMethod类型的变量。
【讨论】:
以上是关于Func<string,string> 和委托有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章
如何从属性名称创建 Expression<Func<TModel, string>> 表达式
表达式<Func<TModel,string>> 到表达式<Action<TModel>> “Getter” 到 “Setter”