4

我试图了解应用程序中的代码块的作用,但我遇到了一些我不明白的 C#。

在下面的代码中,“controller.Progress +=”行之后的代码是做什么的?

我以前没有见过这种语法,而且由于我不知道这些构造被称为什么,所以我无法通过谷歌搜索任何东西来找出这种语法的含义或作用。例如,值 s 和 p 是什么?它们是占位符吗?

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    using (var controller = new ApplicationDeviceController(e.Argument as SimpleDeviceModel))
    {
        controller.Progress += 
           (s, p) => { (sender as BackgroundWorker).ReportProgress(p.Percent); };
        string html = controller.GetAndConvertLog();
        e.Result = html;
    }
}

看起来它正在将一个函数附加到一个事件,但我只是不理解语法(或 s 和 p 是什么),并且该代码没有有用的智能感知。

4

4 回答 4

6

这是一个分配给事件处理程序的 lambda 表达式。

S 和 P 是传递给函数的变量。您基本上是在定义一个无名函数,它接收两个参数。因为 C# 知道 controller.Progress 事件需要一个具有 int 和 object 类型的两个参数的方法处理程序,所以它会自动假定这两个变量属于这些类型。

您也可以将其定义为

controller.Progress += (int s, object p)=> { ... }

这就像你有一个方法定义一样:

controller.Progress += DoReportProgress;
....
public void DoReportProgress(int percentage, object obj) { .... }
于 2013-05-14T14:16:10.233 回答
3

实际上,此代码将 lambda exp 分配给事件。在编译时它将被转换为委托,如下所示,

controller.Progress += new EventHandler(delegate (Object o, EventArgs a) {
a.ReportProgress(p.Percent);
            });
于 2013-05-14T14:18:51.353 回答
3

它被称为匿名函数

匿名函数是一种“内联”语句或表达式,可以在需要委托类型的任何地方使用。您可以使用它来初始化命名委托或将其而不是命名委托类型作为方法参数传递。

在您的场景中,它基本上是连接您的Progress事件以触发该ReportProgess功能。

通常,它会这样写:

controller.Progress += new EventHandler(delegate (object sender, EventArgs a) {
    (sender as BackgroundWorker).ReportProgress(p.Percent);
});
于 2013-05-14T14:16:50.643 回答
3

它连接Progress事件controller以触发BackgroundWorker's ReportProgress

更具体地说,(s, p)是事件处理程序的方法参数签名,例如(object Sender, EventArgs e)

查看lambda 表达式

于 2013-05-14T14:14:57.883 回答