【问题标题】:Need explanation of using lambda as event handler需要解释使用 lambda 作为事件处理程序
【发布时间】:2013-06-21 05:15:34
【问题描述】:

我在answer on stackoverflow 中找到了这段代码。 htmlWeb.PreRequest 似乎不是一个事件处理程序,因为+= tab tab 没有生成所需的代码,并且它在 IntelliSense 中的符号告诉我它是一个普通的成员变量。

请解释一下这个语法。这是一个事件处理程序还是别的什么?我见过+= 通常用于添加事件处理程序。我在 Google 上搜索了诸如“在 c# 中添加事件处理程序的方法”之类的术语,但找不到任何此类代码。

请帮助我理解这段代码。我了解此代码的含义,但不了解语法。任何其他示例将不胜感激。

HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.PreRequest += request =>
{
    request.CookieContainer = new System.Net.CookieContainer();
    return true;
};

【问题讨论】:

  • 非常好的关于 lambda 表达式的文章codeproject.com/Articles/507985/Way-to-Lambda
  • 已更新标题 - 可以随意更改/还原...无法找到您不知道的名称:)
  • 没错,我不知道在标题中放什么。现在很容易搜索。 Thnx @AlexeiLevenkov

标签: c# events event-handling


【解决方案1】:

您的代码:

HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.PreRequest += request =>
{
    request.CookieContainer = new System.Net.CookieContainer();
    return true;
};

实际上相当于:

bool PreRequest_EventHandler(HttpWebRequest request)
{
    request.CookieContainer = new System.Net.CookieContainer();
    return true;
}
//...
HtmlWeb htmlWeb = new HtmlWeb();
htmlWeb.PreRequest += PreRequest_EventHandler;

主要区别在于它使用lambda expressions syntax 而不是声明单独的方法。正如链接的 MSDN 文章中所说,lambda 语法具有以下形式:

(input parameters) => expression

所以您的代码中的request =>输入参数。括号被省略,因为只有一个参数。如果有两个或更多,那就是(x,y)=>...

【讨论】:

  • 感谢@horgh 的精彩解释。我还有一个问题是+= tab tab 在这里不起作用,而不是我应该如何获得事件处理程序的签名..?只阅读文档..?
  • @harsh 抱歉,我没听懂你的意思。 tab 是什么?您可以按 tab 按钮让 Visual Studio 自动生成具有正确签名的单独方法。或者您可以将鼠标悬停在作业的左侧(事件本身),VS 应该给出提示...这是您需要的吗?
  • 无键序列+= Tab Tab 未生成任何代码。 VS intellisense 的 Tooltip 中没有提示
  • 1.您可以使用 F12 按钮进行声明并查看委托的类型和签名。 2. 你可以+= new ,然后 IntelliSense 会建议正确的类型...使用它并添加一个括号 3. 谷歌它
  • Tab 按钮不起作用,因为htmlWeb.PreRequest 是代表,而不是事件。
【解决方案2】:

PreRequest 不是方法,而是委托:

http://htmlagilitypack.codeplex.com/SourceControl/latest#Trunk/HtmlAgilityPack/HtmlWeb.cs

因此,您展示的 lambda 只是为 HtmlAgilityPack 内部使用的所述委托分配了一个匿名方法,以确定是否需要一些额外的工作来正确处理当前请求对象,如下所示:

if (PreRequest != null)
{
    // allow our user to change the request at will
    if (!PreRequest(req))
    {
        return HttpStatusCode.ResetContent;
    }
}

当条件if(!PreRequest(req))...被求值时,它使用匿名方法,向当前请求对象添加一些额外的“东西”,然后返回true(然后!取反),所以HAP知道还没有还没有回来。

如果不是很清楚,不要提供请求对象。 HAP 在使用此委托的 Get() 方法中执行此操作:

req = WebRequest.Create(uri) as HttpWebRequest;

您的委托基本上只是提供一个方法体来可能对该请求执行某些操作,然后返回 true 或 false。

【讨论】:

    【解决方案3】:

    这是Anonymous Methods (C# Programming Guide) 的示例

    在 2.0 之前的 C# 版本中,声明委托的唯一方法 是使用命名方法。 C# 2.0 引入了匿名方法。

    创建匿名方法本质上是一种传递代码块的方法 作为委托参数。

    通过使用匿名方法,您可以减少编码开销 通过消除创建单独的需要来实例化委托 方法。

    所以,基本上,这是使用匿名方法作为事件处理程序。

    【讨论】:

    • 我仍然找不到传递参数的方式。这个叫什么..? += request => ..?没有括号将参数保存在里面。我在 LINQ 中看到过这种情况,但从来没有这样。
    • 参数是request。如果只有一个参数,括号是可选的,但它可以像+= (request) => ...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多