好的,为了清楚起见,我将再次写出这两个内容(并稍微修改方法以使其更短)
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate = (a, b) =>
{
return a.RenderPartial(b);
};
public static string RenderMethod(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
}
首先要注意的是RenderDelegate
是(如 S. DePouw 所写),只是使用 lambda 语法编写以下内容的一种奇特方式:
public static Func<HtmlHelper, PropertyViewModel, string> RenderDelegate =
delegate(HtmlHelper a, PropertyViewModel b)
{
return a.RenderPartial(b);
};
和...之间的不同RenderMethod
and RenderDelegate
就是它RenderMethod
是一种方法,而RenderDelegate
是一个委托,或者更具体地说是一个委托类型的字段。这意味着可以分配给RenderDelegate。
什么是代表?
委托是一种类型。来自MSDN 文档 http://msdn.microsoft.com/en-us/library/ms173171%28VS.80%29.aspx:
委托是一种定义方法签名的类型,可以与具有兼容签名的任何方法关联。
本质上,您可以将委托视为方法的引用/指针,但是委托指向的方法必须与委托所期望的签名相匹配。例如Func<HtmlHelper, PropertyViewModel, string>
是一个需要具有签名的方法的委托string MyMethod(HtmlHelper, PropertyViewModel)
因此我们可以将具有该签名的方法分配给该委托,如下所示:
RenderDelegate = RenderMethod;
重要的是要注意之间的区别Delegate类型(注意大写 D)和delegate关键字(小写 d)。在你的例子中你使用Func<>
通用对象来压缩您的代码,但是它有点模糊了这里真正发生的事情。Func<HtmlHelper, PropertyViewModel, string>
是一个继承自的类型Delegate
,并且您可以使用 delegate 关键字来声明等效类型:
delegate string MyFunction<HtmlHelper helper, PropertyViewModel string>;
static MyFunction RenderDelegate = RenderMethod;
匿名方法
当我们在第一个示例中分配 RenderDelegate 时,我们没有将 RenderDelegate 设置为现有的命名方法,而是内嵌声明了一个新方法。这称为匿名方法并且有效,因为我们能够传递代码块(也使用 delegate 关键字声明)作为委托参数:
Lambda 函数
回到原来的语法 - 你的例子是使用 lambda 语法以一种有趣的方式 delcare 匿名委托。 Lambda 表达式是声明短内联方法的好方法,这些方法通常在处理列表时使用,例如假设我们要按 HtmlHelper 对象的名称对列表进行排序。执行此操作的方法是将比较两个 HtmlHelper 对象的委托传递给列表 Sort 方法,然后排序方法使用该委托对列表中的元素进行比较和排序:
static int MyComparison(HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name);
}
static void Main()
{
List<HtmlHelper> myList = GetList();
myList.Sort(MyComparison);
}
为了避免大量的短方法分散,您可以使用匿名方法来删除内联的排序方法。真正有用的是内联方法可以访问在包含范围内声明的变量:
int myInt = 12;
List<HtmlHelper> myList = GetList();
myList.Sort(
delegate (HtmlHelper x, HtmlHelper y)
{
return x.Name.CompareTo(y.Name) - myInt;
});
然而,这仍然是相当多的输入,所以 lambda 语法诞生了,现在你可以这样做:
List<HtmlHelper> myList = GetList();
myList.Sort((x, y) => {return x.Name.CompareTo(y.Name)});
然而,以这种方式声明“正常”方法对我来说似乎完全没有意义(并且让我的眼睛流血)
代表们是难以置信很有用,并且(除其他外)是 .Net 事件系统的基石。更多阅读内容可以让事情变得更清晰:
- C# 中的委托和事件 http://www.akadia.com/services/dotnet_delegates_and_events.html
- 匿名方法(MSDN 文档) http://msdn.microsoft.com/en-us/library/0yw3tz5k(VS.80).aspx
- lambda 表达式简介 http://www.rvenables.com/2009/03/practical-introduction-to-lambda-expressions/