【问题标题】:.NET 4.0: Parameter naming inconsistency between Expression and MethodInfo.NET 4.0:Expression 和 MethodInfo 之间的参数命名不一致
【发布时间】:2010-09-06 20:51:19
【问题描述】:

我刚刚在使用 System.Linq.Expressions.Expression 和 System.Reflection.MethodInfo 时发现了一些神秘的行为。

代码如下:

    static void Main(string[] args)
    {

        Expression<Func<double, double, double>> example = (x, y) => Math.Sin(x);

        //Prints out "x, y":
        Console.WriteLine(example.Parameters[0].Name + ", " + example.Parameters[1].Name);

        //Prints out "a":
        Console.WriteLine((example.Body as MethodCallExpression).Method.GetParameters()[0].Name);

    }

“一个”?我的“x”去哪儿了,这个“a”又是从哪里来的?

认为这可能是低级别使用的别名,我搜索了“UsedName”、“VisibleName”或类似的东西,但我没有找到任何东西。

不幸的是,Expression 没有Parameters 属性(我相信只有LambdaExpression 有),它会在给定表达式中返回“使用中的参数”(如果有的话)。

可以创建一个遍历整个表达式并收集使用中的不同参数的方法,但我想知道是否有更简单的方法来做到这一点。

非常感谢。

Visual C# Express:10.0.30319.1 RTMRel

.NET 框架:4.0.30319 RTMRel

【问题讨论】:

    标签: .net reflection lambda expression expression-trees


    【解决方案1】:

    a 来自您调用的方法 - Math.Sinxy 是 lambda 表达式的参数; aMath.Sin中的参数。

    如果您想返回 xy,请将 example 转换为 LambdaExpression

    foreach (ParameterExpression p in example.Parameters)
    {
        Console.WriteLine(p.Name); // Prints x then y
    }
    

    所以不,这里没有矛盾。

    编辑:如果你想找到方法调用中使用的参数 - 并且你确定它 is 只是一个方法调用,而参数只是参数 - 你可以使用类似:

    var methodCall = (MethodCallExpression) example.Body;
    
    // Implicitly casts each argument to ParameterExpression
    foreach (ParameterExpression p in methodCall.Arguments)
    {
        Console.WriteLine(p.Name);
    }
    

    在这种情况下,它只会打印出 x,因为这就是 Math.Sin 的参数。

    【讨论】:

    • 现在我明白我并没有真正将苹果与苹果进行比较,因此同意没有不一致之处。另一方面:为什么演员?我已经可以直接从example 访问ParametersBody 等,(我相信)它的类型是LambdaExpression。我认为真正有用的是这样的:ParameterExpression[] parameters = (anyExpressionInstance as LambdaExpression).Parameters.ToArray();。在这种特定情况下,(example.Body as LambdaExpression) 将变为 x =&gt; Math.Sin(x),我可以从中检索“正在使用的参数”x
    • @Blas: 是的 - 因为你的段落以“不幸”开头 - 我忘记了你实际上有一个 Expression&lt;T&gt;,而不仅仅是一个 Expression. So yes, you don't need the cast. I'll edit my answer. Personally I would cast rather than using as ` 但是,在您的注释代码中 - NullReferenceException 不如 InvalidCastException 有用。
    • @Blas:只是重读你的评论,听起来你想要方法调用的 arguments。正在编辑...
    【解决方案2】:

    在 Visual Studio 中将光标放在 Sin 上。按 F12 键。这就是a 的来源。它来自雷德蒙德的一位开发人员,他决定将其命名为 :-)

    【讨论】:

    • 我明白了,所以“a”只是函数 Sin 的“硬编码”参数名称。
    • 是的,这就是它的来源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    相关资源
    最近更新 更多