C# Expression.Variable()和Expression.Parameter()之间有什么区别?

C# Expression.Variable()和Expression.Parameter()之间有什么区别?,c#,.net,expression,expression-trees,C#,.net,Expression,Expression Trees,两者似乎返回相同的类型,并且具有相同的签名 那么它们之间的区别是什么,我们应该在什么时候使用它们呢?Expression.Variable用于声明块中的局部变量表达式。参数用于为传入值声明参数 现在,C#不允许语句体lambda表达式,但如果它允许,想象一下: // Not currently valid, admittedly... Expression<Func<int, int>> foo = x => { int y = DateTime.Now.H

两者似乎返回相同的类型,并且具有相同的签名


那么它们之间的区别是什么,我们应该在什么时候使用它们呢?

Expression.Variable
用于声明块中的局部变量<代码>表达式。参数用于为传入值声明参数

现在,C#不允许语句体lambda表达式,但如果它允许,想象一下:

// Not currently valid, admittedly...
Expression<Func<int, int>> foo = x =>
{
    int y = DateTime.Now.Hour;
    return x + y;
};
//目前无效,诚然。。。
表达式foo=x=>
{
int y=DateTime.Now.Hour;
返回x+y;
};

如果这是有效的,C#编译器将使用
Expression.Parameter
x
,使用
Expression.Variable
y
生成代码


至少,这是我的理解。这两种方法的文档基本上是相同的,这真是一个遗憾:(

实际上,除了
Variable()
不允许
ref
类型之外,没有区别。要了解这一点,您可以看一下:


正如您所看到的,这两个方法都调用
参数Expression.Make()
,因此返回的对象的行为将相同。

Expression.Variable
不允许
ByRef
类型。谢谢Jon!但是由于它们返回相同的类型,它们不只是语义上的不同吗?@shay\uuuuuu:我不知道您的意思“只是语义不同”,因为语义就是意义。我希望Expression.Variable的结果传递到Expression.Lambda中是无效的。例如,很遗憾,它们是同一类型。是的,这就是我的意思-你可以调用Expression.Parameter或Expression.Variable,实际上它不会有任何区别。By”语义上“我的意思是功能是相同的,但它们对读者或未来的功能有不同的名称……对吗?@shay_uuu:不,我希望它们的行为会有所不同,就像我建议的那样。它们可能不会,但你必须进行实验来检查。(或查看源代码)。实际上,你可以“发射”“该代码在C#4.0及更高版本中使用表达式.Block API。
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);
}