我正在阅读这份文件,其中一条注释是,
您可能希望始终使用ValueTuple而不是Tuple和匿名类型,但您应该考虑一些折衷方案。ValueTuple类型是可变的,而Tuple是只读的匿名类型可以在表达式树中使用,而元组不能下表概述了一些关键差异。[强调矿]
这不是关于元组或匿名类型本身的问题,而是关于概念的问题。
表达式树在.NET中表示为指向其他对象的对象,这些对象又指向其他对象。例如,考虑以下表达式树:
Expression expr = () => DateTime.Now.Hour > 18;
实际上,我们不能在System.Linq.Expressions
中的大多数类型上编写new <X>
。但是,如果我们可以把表达式树写成一系列对象创建和初始化,它可能看起来像这样:
new Expression<Func<bool>> {
NodeType = ExpressionType.Lambda,
Type = typeof(Func<bool>),
Body = new BinaryExpression {
NodeType = ExpressionType.GreaterThan,
Type = typeof(bool),
Left = new MemberExpression {
Type = typeof(int),
Expression = new MemberExpression {
Type = typeof(DateTime),
Member = typeof(DateTime).GetProperty("Now")
},
Member = typeof(DateTime).GetProperty("Hour")
},
Right = new ConstantExpression {
Type = typeof(int),
Value = 18
}
},
ReturnType = typeof(bool)
}
有两种创建表达式树的基本方法:
让编译器执行此操作。将lambda表达式语法设置为
Expression<TDelegate>
类型的变量、属性或参数。C#编译器会自动将您编写的代码转换为一个完整的表达式树(如上所述(。调用
System.Linq.Expressions.Expression
上的工厂方法类似这样的东西:// using static System.Linq.Expressions.Expression Lambda( GreaterThan( MakeMemberAccess( MakeMemberAccess(null, typeof(DateTime).GetProperty("Now") ), typeof(DateTime).GetProperty("Hour") ), Constant(18) ) )
因为C#编译器中创建表达式树的部分已经很长时间没有更新了,所以它无法处理许多较新的C#构造(如值元组(。
但是,您总是可以使用工厂方法,并使用您可能想要的任何.NET类型来构造表达式树。
(注意。我写了一个库,可以生成表达式树的字符串表示,比如这个答案中的那些。(