C# 为什么表达式构造函数隐藏在c中#
我目前正在研究如何按照.Net创建表达式的方式构建一些东西,我正在研究C# 为什么表达式构造函数隐藏在c中#,c#,linq,C#,Linq,我目前正在研究如何按照.Net创建表达式的方式构建一些东西,我正在研究Linq中的expressions类,我很困惑为什么它们会沿着Expression.Call(Params)的路线运行,而不是像new CallExpression(Params) 我的第一个猜测是可读性,或者他们对您隐藏了真实的类定义,使其更具弹性。如果您使用反编译器查看源代码,您会发现调用如下所示: [__DynamicallyInvokable] public static MethodCallExpression Ca
Linq
中的expressions
类,我很困惑为什么它们会沿着Expression.Call(Params)
的路线运行,而不是像new CallExpression(Params)
我的第一个猜测是可读性,或者他们对您隐藏了真实的类定义,使其更具弹性。如果您使用反编译器查看源代码,您会发现调用如下所示:
[__DynamicallyInvokable]
public static MethodCallExpression Call(Expression instance, MethodInfo method, IEnumerable<Expression> arguments)
{
ContractUtils.RequiresNotNull((object) method, "method");
ReadOnlyCollection<Expression> arguments1 = CollectionExtensions.ToReadOnly<Expression>(arguments);
Expression.ValidateMethodInfo(method);
Expression.ValidateStaticOrInstanceMethod(instance, method);
Expression.ValidateArgumentTypes((MethodBase) method, ExpressionType.Call, ref arguments1);
if (instance == null)
return (MethodCallExpression) new MethodCallExpressionN(method, (IList<Expression>) arguments1);
return (MethodCallExpression) new InstanceMethodCallExpressionN(method, instance, (IList<Expression>) arguments1);
}
[[uuu\u DynamicallyInvokable]
公共静态MethodCallExpression调用(表达式实例、MethodInfo方法、IEnumerable参数)
{
RequiresNotNull((对象)方法,“方法”);
ReadOnlyCollection arguments1=CollectionExtensions.ToReadOnly(参数);
表达式.ValidateMethodInfo(方法);
Expression.ValidateStaticOrInstanceMethod(实例,方法);
Expression.ValidateArgumentTypes((MethodBase)方法,ExpressionType.Call,ref arguments1);
if(实例==null)
返回(MethodCallExpression)新方法CallExpressionn(方法,(IList)参数1);
返回(MethodCallExpression)新实例MethodCallExpressionn(方法,实例,(IList)参数1);
}
您会注意到,尽管调用类型是MethodCallExpression
,但方法中实际返回的类型是MethodCallExpressionN
&InstanceMethodCallExpressionN
。这两个是MethodCallExpression
的内部子类
因此,静态方法根据给定的参数强制执行正确的逻辑以返回正确的类型。如果您能够直接调用构造函数,您就不会得到这样的结果。最明显的原因之一是使用工厂方法允许泛型类型参数推断。我想可能还有其他架构动机,但类型推断有助于防止基于
表达式的代码变得比现在更为冗长。在某些情况下,返回声明的返回类型的内部子类型可能会很有用。例如,Expression.Field
返回一个FieldExpression
,但该类型不是公共类型。如果用户直接实例化具体的类,那么这种间接寻址是不可能的。此外,由于这是一个实现细节,因此将来可能会发生变化。这将归结为静态工厂/外观的好处。这就是我所想的,我不敢相信我没有想到反编译,herp derp。