我已经快速阅读了Microsoft Lambda表达式文档。

不过,这样的例子帮助我更好地理解:

delegate int del(int i);
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25

不过,我还是不明白为什么这是一种创新。它只是一个在“方法变量”结束时死亡的方法,对吧?为什么我要用这个而不是真正的方法?


当前回答

当我想使用另一个控件为某个控件的事件声明一个处理程序时,我发现它们很有用。 要做到这一点,你必须将控件的引用存储在类的字段中,这样你就可以在不同的方法中使用它们。

private ComboBox combo;
private Label label;

public CreateControls()
{
    combo = new ComboBox();
    label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += new EventHandler(combo_SelectedIndexChanged);
}

void combo_SelectedIndexChanged(object sender, EventArgs e)
{
    label.Text = combo.SelectedValue;
}

多亏了lambda表达式,你可以这样使用它:

public CreateControls()
{
    ComboBox combo = new ComboBox();
    Label label = new Label();
    //some initializing code
    combo.SelectedIndexChanged += (s, e) => {label.Text = combo.SelectedValue;};
}

容易得多。

其他回答

这是一种将小操作放在非常接近使用位置的地方的方法(与在接近使用点的地方声明变量没有什么不同)。这将使您的代码更具可读性。通过匿名化表达式,如果在其他地方使用了该函数并对其进行了修改以“增强”它,那么其他人就很难破坏您的客户端代码。

同样,为什么需要使用foreach?你可以用一个简单的for循环来完成foreach中的所有事情,或者直接使用IEnumerable。答案:你不需要它,但它使你的代码更可读。

这样可以避免在远离使用方法的地方定义只在特定位置使用一次的方法。好的用途是作为泛型算法(如排序)的比较器,然后您可以定义一个自定义排序函数,在该函数中调用排序,而不是进一步迫使您查看其他地方以查看您正在排序的对象。

这并不是真正的创新。LISP拥有lambda函数已经有30年或更长时间了。

这只是使用lambda表达式的一种方式。你可以在任何可以使用委托的地方使用lambda表达式。这允许你做这样的事情:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

strings.Find(s => s == "hello");

这段代码将在列表中搜索与单词“hello”匹配的条目。另一种方法是传递一个委托给Find方法,像这样:

List<string> strings = new List<string>();
strings.Add("Good");
strings.Add("Morning")
strings.Add("Starshine");
strings.Add("The");
strings.Add("Earth");
strings.Add("says");
strings.Add("hello");

private static bool FindHello(String s)
{
    return s == "hello";
}

strings.Find(FindHello);

编辑:

在c# 2.0中,这可以使用匿名委托语法完成:

  strings.Find(delegate(String s) { return s == "hello"; });

Lambda明显地清理了语法。

匿名函数和表达式对于一次性方法非常有用,这些方法不需要从创建完整方法所需的额外工作中获益。

想想这个例子:

 List<string> people = new List<string> { "name1", "name2", "joe", "another name", "etc" };
 string person = people.Find(person => person.Contains("Joe"));

 public string FindPerson(string nameContains, List<string> persons)
 {
     foreach (string person in persons)
         if (person.Contains(nameContains))
             return person;
     return null;
 }

它们在功能上是等价的。

Lambda清理了c# 2.0的匿名委托语法…例如

Strings.Find(s => s == "hello");

在c# 2.0中是这样完成的:

Strings.Find(delegate(String s) { return s == "hello"; });

在功能上,它们做的是完全相同的事情,只是语法更简洁。