编译后,它们之间是否有区别:
delegate { x = 0; }
和
() => { x = 0 }
?
编译后,它们之间是否有区别:
delegate { x = 0; }
和
() => { x = 0 }
?
Answers:
简短的回答:不。
更长的答案可能不相关:
Func
或Action
),则将获得一个匿名委托。编辑:这是表达式的一些链接。
我喜欢艾米(Amy)的回答,但我认为我会做书呆子。这个问题说,“一旦它编译” -这表明两个表达式都被编译。它们都如何编译,但是其中一个被转换为委托,另一个被转换为表达式树?这是一个棘手的问题-您必须使用匿名方法的另一功能;唯一不被lambda表达式共享的表达式。如果您指定一个匿名方法而不指定任何参数列表,则它与返回void且没有任何out
参数的任何委托类型兼容。掌握了这些知识之后,我们应该能够构造两个重载,以使表达式完全明确而又非常不同。
但是灾难来袭!至少在C#3.0中,您不能将带有块主体的lambda表达式转换为表达式-也不能在主体中具有赋值的情况下转换lambda表达式(即使将其用作返回值)。这可能会随着C#4.0和.NET 4.0的变化而改变,从而允许在表达式树中表达更多内容。因此,换句话说,借助MojoFilter给出的示例,几乎总是将两者转换为同一件事。(稍后会详细介绍。)
如果稍微改变一下主体,我们可以使用委托参数技巧:
using System;
using System.Linq.Expressions;
public class Test
{
static void Main()
{
int x = 0;
Foo( () => x );
Foo( delegate { return x; } );
}
static void Foo(Func<int, int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
static void Foo(Expression<Func<int>> func)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
可是等等!如果我们足够狡猾的话,即使不使用表达式树,我们也可以区分两者。下面的示例使用重载解析规则(和匿名委托匹配技巧)...
using System;
using System.Linq.Expressions;
public class Base
{
public void Foo(Action action)
{
Console.WriteLine("I suspect the lambda expression...");
}
}
public class Derived : Base
{
public void Foo(Action<int> action)
{
Console.WriteLine("I suspect the anonymous method...");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int x = 0;
d.Foo( () => { x = 0; } );
d.Foo( delegate { x = 0; } );
}
}
哎哟。记住孩子们,每当您重载从基类继承的方法时,一只小猫就会开始哭泣。
delegate { ... }
是不一样的delegate() { ... }
-后者只与一个无参数的委托类型兼容。
艾米B是正确的。请注意,使用表达式树可能会有好处。LINQ to SQL将检查表达式树并将其转换为SQL。
您还可以使用lamda和表达式树来玩弄技巧,以有效的重构安全方式将类成员的名称有效地传递给框架。 最小起订量就是一个例子。
它们是有区别的
例:
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(delegate
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
我用lambda代替:(错误)
var mytask = Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
return 2712;
});
mytask.ContinueWith(()=>
{
_backgroundTask.ContinueTask(() =>lblPercent.Content = mytask.Result.ToString(CultureInfo.InvariantCulture));
});
这里有一些基础知识。
这是一个匿名方法
(string testString) => { Console.WriteLine(testString); };
由于匿名方法没有名称,因此我们需要一个委托,在其中可以分配这两种方法或表达式。例如
delegate void PrintTestString(string testString); // declare a delegate
PrintTestString print = (string testString) => { Console.WriteLine(testString); };
print();
与lambda表达式相同。通常我们需要一个委托来使用它们
s => s.Age > someValue && s.Age < someValue // will return true/false
我们可以使用func委托来使用此表达式。
Func< Student,bool> checkStudentAge = s => s.Age > someValue && s.Age < someValue ;
bool result = checkStudentAge ( Student Object);