有人可以告诉我使用委托的优势而不是如下所示调用函数本身(或者换句话说为什么选择选项A而不是选项B)?我昨晚看了某人的linq代码,他们有类似于Option A的东西,但它被用来返回编译的linq查询。
我意识到前者现在可以传递给其他功能......只是不确定它的实用性。顺便说一句,我意识到这不会按原样编译..在发布之前取消注释其中一个功能。 TYIA
class Program
{
static void Main(string[] args)
{
Console.WriteLine(SayTwoWords("Hello", "World"));
Console.ReadKey();
}
// Option A
private static Func<string, string, string>
SayTwoWords = (a, b) => String.Format("{0} {1}", a, b);
// Option B
private static string SayTwoWords(string a, string b)
{
return String.Format("{0} {1}", a, b);
}
}
************ EDIT ************
不确定它是否更好地解释了我的问题,但这里是一个最初让我思考这个问题的代码类型的例子:
public static class clsCompiledQuery
{
public static Func<DataContext, string, IQueryable<clsCustomerEntity>>
getCustomers = CompiledQuery.Compile((DataContext db, string strCustCode)
=> from objCustomer in db.GetTable<clsCustomerEntity>()
where objCustomer.CustomerCode == strCustCode
select objCustomer);
}
以这种方式编写函数有什么好处吗?
答案 0 :(得分:13)
您发布的代码没有任何优势。在您的代码中,使用委托只会增加复杂性以及额外的运行时成本 - 因此您最好直接调用该方法。
然而,代表有很多用途。 “传递”到其他方法是主要用法,虽然存储函数并在以后使用它也非常有用。
LINQ完全基于这个概念。当你这样做时:
var results = myCollection.Where(item => item == "Foo");
您将委托(定义为lambda:item => item == "Foo"
)传递给LINQ库中的Where
函数。这是使它正常工作的原因。
答案 1 :(得分:4)
代表的一个非常有用的功能是你可以在任何你想要的地方发送它们。就像在任何地方都需要你的功能一样。一个很重要的用途是事件处理。假设您有一个按钮,当用户单击此按钮时,您希望调用任意数量的函数。如果你想到这一点,有几种方法可以做到这一点:
你可以: 调用一个调用你想要调用的其他函数的函数。 这意味着对于要调用的每个新函数,必须将其硬编码到此函数中。非常烦人。
OR 您可以拥有要呼叫的每个功能的名称的公共列表(代表),任何人都可以随时添加或删除这些功能,而点击事件的所有者不必知道甚至不做任何有关它们的任何工作。当click事件发生时,列表中的每个事件都会被调用并发送相同的参数,您就完成了。
答案 2 :(得分:3)
只有在必须传递委托时才有用。如果你可以在编译时解决这个问题,那就不太有用了。
答案 3 :(得分:2)
答案 4 :(得分:1)
答案 5 :(得分:1)
// Option A
private static Func<string, string, string>
SayTwoWords = (a, b) => String.Format("{0} {1}", a, b);
// Option B
private static string SayTwoWords(string a, string b)
{
return String.Format("{0} {1}", a, b);
}
在上述情况下,选项B是我要使用的,除非我需要更改SayTwoWords
的功能。在选项A的情况下,可以为SayTwoWords
分配不同的功能。抓住更详细的差异in this answer:
存在选项A有意义的情况。考虑一种必须将表达式编译为委托的情况。由于编译表达式很重,所以你只想做一次。这样的模式有助于:
public static class Cache<T>
{
public static readonly Func<T> Get = GetImpl();
static Func<T> GetImpl()
{
//build expression and return compiled delegate
}
}
而不是
public static class Cache<T>
{
public static T Get()
{
//build expression, compile delegate and invoke the delegate
}
}
在第一种情况下,当您致电Get
时,GetImpl
仅执行一次,而在第二种情况下,每次都会调用(昂贵的)Get
。