Expression.Variable() 和 Expression.Parameter() 有什么区别?
What is the difference between Expression.Variable() and Expression.Parameter()?
两者似乎 return 类型相同,并且具有相同的签名。
那么它们之间有什么区别,我们应该在什么时候使用它们?
Expression.Variable
用于声明块内的局部变量。 Expression.Parameter
用于为传入值声明参数。
目前 C# 不允许使用语句主体的 lambda 表达式,但如果它做到了,想象一下:
// Not currently valid, admittedly...
Expression<Func<int, int>> foo = x =>
{
int y = DateTime.Now.Hour;
return x + y;
};
如果此 是 有效,C# 编译器将使用 Expression.Parameter
为 x
和 Expression.Variable
为 y
生成代码].
至少,这是我的理解。很遗憾这两种方法的文档基本相同:(
实际上,除了 Variable()
不允许 ref
类型之外,没有区别。要了解这一点,您可以查看 the reference source:
public static ParameterExpression Parameter(Type type, string name) {
ContractUtils.RequiresNotNull(type, "type");
if (type == typeof(void)) {
throw Error.ArgumentCannotBeOfTypeVoid();
}
bool byref = type.IsByRef;
if (byref) {
type = type.GetElementType();
}
return ParameterExpression.Make(type, name, byref);
}
public static ParameterExpression Variable(Type type, string name) {
ContractUtils.RequiresNotNull(type, "type");
if (type == typeof(void)) throw Error.ArgumentCannotBeOfTypeVoid();
if (type.IsByRef) throw Error.TypeMustNotBeByRef();
return ParameterExpression.Make(type, name, false);
}
如您所见,这两个方法都调用了 ParameterExpression.Make()
,因此返回的对象的行为相同。
两者似乎 return 类型相同,并且具有相同的签名。
那么它们之间有什么区别,我们应该在什么时候使用它们?
Expression.Variable
用于声明块内的局部变量。 Expression.Parameter
用于为传入值声明参数。
目前 C# 不允许使用语句主体的 lambda 表达式,但如果它做到了,想象一下:
// Not currently valid, admittedly...
Expression<Func<int, int>> foo = x =>
{
int y = DateTime.Now.Hour;
return x + y;
};
如果此 是 有效,C# 编译器将使用 Expression.Parameter
为 x
和 Expression.Variable
为 y
生成代码].
至少,这是我的理解。很遗憾这两种方法的文档基本相同:(
实际上,除了 Variable()
不允许 ref
类型之外,没有区别。要了解这一点,您可以查看 the reference source:
public static ParameterExpression Parameter(Type type, string name) {
ContractUtils.RequiresNotNull(type, "type");
if (type == typeof(void)) {
throw Error.ArgumentCannotBeOfTypeVoid();
}
bool byref = type.IsByRef;
if (byref) {
type = type.GetElementType();
}
return ParameterExpression.Make(type, name, byref);
}
public static ParameterExpression Variable(Type type, string name) {
ContractUtils.RequiresNotNull(type, "type");
if (type == typeof(void)) throw Error.ArgumentCannotBeOfTypeVoid();
if (type.IsByRef) throw Error.TypeMustNotBeByRef();
return ParameterExpression.Make(type, name, false);
}
如您所见,这两个方法都调用了 ParameterExpression.Make()
,因此返回的对象的行为相同。