在这个问题之后,我想知道lambda参数表达式实例的重用是否应该被认为是好的还是坏的?
我有时会得到一个完整的LINQ表达式树,其中同一个lambda参数实例在第二个非生成的lambda中正确使用:
// class Person { public int AProp { get; set; } public bool BProp { get; set; }}
var lparam = Expression.Parameter(typeof(Person),"x");
var lambda1 = (Expression<Func<Person,int>>)Expression.Lambda(Expression.Property(lparam, "AProp"), lparam);
var lambda2 = (Expression<Func<Person,bool>>)Expression.Lambda(Expression.Property(lparam, "BProp"), lparam);
var source = (new Person[0]).AsQueryable();
var query = source.Where(lambda2).OrderBy(lambda1); 
因此,对于lambda1和lambda2,同一lambda参数实例lparam的声明是正确的.
只是这个共享的lambda参数实例强制IQueryProvider实现不基于纯lambda参数引用关联其他全局含义,因为在处理不同的lambda期间可能需要以不同方式解释相同的参数.另外,你不会通过使用从LINQ获得这种表达式树(或者我应该说图形?)
Expression<Func<Person,int>> lambda3 = x => x.AProp;
Expression<Func<Person,bool>> lambda4 = x => x.BProp;
因为两个lambda表达式都会有(Person x)的不同参数实例.同样的道理
var query = source.Where(x => x.BProp).OrderBy(x => x.AProp);
要么
var query = from x in source where x.BProp order by x.AProp select x;
它还使表达式树成为一个图形.
这种参数实例的重用方式是好还是坏?到目前为止,我还没有从当局那里找到明确答案.
我不会在两个不相交的lambda之间共享一个参数对象.
首先,我们不要在这里制造虚假经济.物品价格便宜,你不会赚到十万.(如果你是,你可能有更大的问题需要解决.)
其次,正如您所注意到的,在不相关的lambdas之间共享引用相同的参数对象意味着需要分析这些lambda表达式树的代码来理解参数对象在不同的上下文中具有不同的含义.这似乎是一个等待发生的错误.
第三,有人想象有一天你可能想要带两个表达式树:
x => Foo(x);
y => Bar(y);
并从他们建立第三,说:
(x,y) => Foo(x) && Bar(y);
如果x和y实际上都是同一个参数对象,那么你手上就有问题:
(x,x) => Foo(x) && Bar(x);  // Huh?
另一方面,StriplingWarrior的答案指出,如果你有
x => Foo(x);
x => Bar(x);
然后将它们组合起来更容易
x => Foo(x) && Bar(x);
因为那时你就不会需要重写任何东西.
基本上,这似乎是一个冒险的举措,没有真正令人信服的上行空间,为什么呢?