有人可以解释一下这个 C# lambda 语法吗?

2024-03-29

我最近发现了一个静态方法,声明为:

public class Foo
{
  public static Func<HtmlHelper, PropertyViewModel, string> Render = (a, b) =>
  {
    a.RenderPartial(b);
    return "";
  };
}

Intellisense 建议的用法是(例如):

string s = Foo.Render(htmlHelper, propertyViewModel);

那么看起来以下是等价的:

public static string Render(HtmlHelper a, PropertyViewModel b)
{
  a.RenderPartial(b);
  return "";
}

A) 第一个样式的名称是什么?我意识到它正在使用 lambda;这是=那个让我绊倒的标志。我无法标记它;)

B) 如果两个代码块are等价,使用前者比后者有什么好处?


好的,为了清楚起见,我将再次写出这两个内容(并稍微修改方法以使其更短)

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/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有人可以解释一下这个 C# lambda 语法吗? 的相关文章

  • 有没有快速创建集合的方法?

    目前我正在创建一个像这样的新集 std set a s s insert a1 s insert a2 s insert a3 s insert a10 有没有办法创建s在一行 int myints 10 20 30 40 50 std s
  • 如何在 C# / .NET 中创建内存泄漏[重复]

    这个问题在这里已经有答案了 可能的重复 托管代码中是否可能存在内存泄漏 特别是 C 3 0 https stackoverflow com questions 6436620 is it possible to have a memory
  • 平滑滚动.net 表单

    您好 我正在 net 中使用表单 并且在运行时动态添加大量链接标签 我将这些链接标签添加到面板并将该面板添加到 winform 当链接标签的数量增加时 表单会显示一个自动滚动条 垂直 现在 当我使用自动滚动向下滚动时 表单在滚动时不会更新其
  • 根据 N 个值中最小的一个返回不同的结果

    不确定如何使标题更具描述性 所以我只是从一个例子开始 我使用下面的代码位 它从枚举中选择一个方向 具体取决于四个轴中哪一个与给定方向相比形成最小角度 static Direction VectorToDirection Vector2 di
  • 与 Qt 项目的静态链接

    我有一个在 Visual Studio 2010 Professional 中构建的 Qt 项目 但是 当我运行它 在调试或发布模式下 时 它会要求一些 Qt dll 如果我提供 dll 并将它们放入 System32 中 它就可以工作 但
  • ASP.Net Core 内容配置附件/内联

    我正在从 WebAPI 控制器返回一个文件 Content Disposition 标头值自动设置为 附件 例如 处置 附件 文件名 30956 pdf 文件名 UTF 8 30956 pdf 当它设置为附件时 浏览器将要求保存文件而不是打
  • 如何获取 QTableView 的标题列表?

    我有一个QTableView我的对话框中的对象 我需要访问该表的水平标题并将它们放入QStringList object 尽管进行了大量搜索 但我在 Qt 文档中找不到如何获取此标头列表 编辑 我发现的最接近的地方是this https w
  • 在 JSQMessagesViewController 中显示 LocationMediaItem

    我刚刚尝试实施LocationMediaItem in my Xamarin iOS应用程序使用JSQMessagesViewController 一切都很顺利 唯一的问题是UICollectionView应该显示位置的单元格永远停留在加载
  • 如何从文本文件读取整数到数组

    这就是我想做的 我对此有些不满 但我希望你能容忍我 这对我来说是一个非常新的概念 1 在我的程序中 我希望创建一个包含 50 个整数的数组来保存来自文件的数据 我的程序必须获取用户的文档文件夹的路径 2 文件的名称为 grades txt
  • 如何在服务器端按钮点击时关闭当前标签页?

    我尝试在确认后关闭当前选项卡 因此我将以下代码放在确认按钮的末尾 但选项卡没有关闭 string jScript ClientScript RegisterClientScriptBlock this GetType keyClientBl
  • AES 输出是否小于输入?

    我想加密一个字符串并将其嵌入到 URL 中 因此我想确保加密的输出不大于输入 AES 是可行的方法吗 不可能创建任何始终会创建比输入更小的输出的算法 但可以将任何输出反转回输入 如果您允许 不大于输入 那么基本上您只是在谈论同构算法alwa
  • 将标量添加到特征矩阵(向量)

    我刚刚开始使用 Eigen 库 无法理解如何向所有矩阵成员添加标量值 假设我有一个矩阵 Eigen Matrix3Xf mtx Eigen Matrix3Xf Ones 3 4 mtx mtx 1 main cxx 104 13 error
  • 如何在c的case语句中使用省略号?

    CASE expr no commas ELLIPSIS expr no commas 我在c的语法规则中看到了这样的规则 但是当我尝试重现它时 int test float i switch i case 1 3 printf hi 它失
  • C# 中的 strstr() 等效项

    我有两个byte 我想找到第二个的第一次出现byte 在第一个byte 或其中的一个范围 我不想使用字符串来提高效率 翻译第一个byte to a string会效率低下 基本上我相信就是这样strstr 在 C 中做 最好的方法是什么 这
  • 使用restsharp序列化对象并将其传递给WebApi而不是序列化列表

    我有一个看起来像的视图模型 public class StoreItemViewModel public Guid ItemId get set public List
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • 在简单注入器中解析具有自定义参数的类

    我正在使用以下命令创建 WPF MVVM 应用程序简易注射器作为 DI 容器 现在 当我尝试从简单注入器解析视图时遇到一些问题 因为我需要在构造时将参数传递到构造函数中 而不是在将视图注册到容器时 因此这不是适用的 简单注入器将值传递到构造
  • QFileDialog::getSaveFileName 和默认的 selectedFilter

    我有 getSaveFileName 和一些过滤器 我希望当用户打开 保存 对话框时选择其中之一 Qt 文档说明如下 可以通过将 selectedFilter 设置为所需的值来选择默认过滤器 我尝试以下变体 QString selFilte
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • 从 JavaScript 中的 OnClientClick 事件中阻止 C# 中的 asp:Button OnClick 事件?

    我有一个asp Button在我的网页上 它调用 JavaScript 函数和代码隐藏方法 后者进行调用以导航到另一个页面 在 JavaScript 函数中 我正在检查条件 如果不满足这个条件 我想中止导航 以便OnClick方法未被调用

随机推荐