在获取局部变量(和参数)的名称运行时通过lambda表达式在获取局部变量(和参数)的名称运行时通过l

2019-06-01 04:51发布

我感兴趣的是在重构安全的方式检索在运行时局部变量(和参数)的名称。 我有以下的扩展方法:

public static string GetVariableName<T>(Expression<Func<T>> variableAccessExpression)
{
    var memberExpression = variableAccessExpression.Body as MemberExpression;
    return memberExpression.Member.Name;
}

...返回通过lambda表达式捕获的变量的名称:

static void Main(string[] args)
{
    Console.WriteLine(GetVariableName(() => args));
    // Output: "args"

    int num = 0;
    Console.WriteLine(GetVariableName(() => num));
    // Output: "num"
}

然而,这只是工作,因为C#编译器促进了在匿名函数幕后编译器生成的类(每个内捕获到同名的实例变量的任何局部变量(和参数) 乔恩斯基特 )。 如果不是这种情况下,投BodyMemberExpression会失败,因为MemberExpression代表字段或属性的访问。

这个变量的推广记录的行为,或者是它的实现细节主题框架中的其他版本的改变?

注意:这个问题的概括我对参数验证前者 。

Answer 1:

更新 :这不再是从C#6,它推出了一个问题nameof运营商来解决这样的场景(参见MSDN )。

看来,回答我的问题是否定的; 该功能是不规范。 这种情况似乎更加暗淡比我最初怀疑; 不仅是促进捕获变量非标准化的,但这样是将匿名函数来表达自己的树表示整个规范。

这样做的含义是,即使简单的匿名功能,如下面的,不能保证导致在整个框架(直至转换标准化)的不同的实施方式一致的表达式树:

Expression<Func<int, int, int>> add = (int x, int y) => x + y;

以下摘录是从所拍摄的C#语言规范4.0 (着重在所有情况下添加)。

从“4.6表达式树类型”:

所述类型的确切定义Expression<D>以及用于构建表达树当一个匿名函数转换为表达式树类型的精确的规则, 都本说明书的范围之外 ,并且其他地方描述的。

从“6.5.2评价匿名函数转换到表达式树类型”:

一个匿名函数到表达式树类型的转换产生一个表达式树(§4.6)。 更确切地说,匿名函数转换的评估导致表示匿名函数本身的结构对象结构的施工。 表达式树的精确结构,以及用于创建它的确切过程中,被实现定义。

在“6.5.3实现示例”的第三个例子表明,捕获一个局部变量的匿名函数转换,并证实了我的问题中提到的变量推广:

局部变量的生存期,现在必须延长到匿名函数委托的至少寿命。 这可以通过“吊装”局部变量来实现成一个编译器生成的类的字段。 局部变量(§7.15.5.2)的实例化,然后对应于创建编译器生成的类的一个实例,并访问本地变量对应于在编译程序生成类的实例访问字段

这是在该部分的端部进一步证实:

捕捉局部变量这里所应用的同样的技术也可以被转换匿名函数到表达式树时使用:参考文献到编译器生成的对象可以被存储在表达式树,并作为字段访问这些对象可以被表示访问本地变量 。 这种方法的优点是,它允许“解禁”局部变量来代表和表达式树之间共享。

然而,在本节开始时的声明:

这里描述的实现是基于微软的C#编译器所使用的相同的原则,但它绝不是一个强制性的实现,也不是只有一种可能 。 它只是简单地提到了转换到表达式树,因为它们的准确语义是本规范的范围之内。

PS埃里克利珀证实了此评论的表达式树的规格从来没有发货。 存在一个表达式树V2规格 CodePlex上的DLR文件之下,但其范围似乎并不涵盖的匿名函数表达式树在C#中的转换。



Answer 2:

这是你应该依赖行为。

看看C#lambda表达式或语法的辉煌滥用?

现在读埃里克利珀谁在C#设计团队的意见。 他们包括:

我刚才问安德斯(和设计团队的其他成员),他们在想什么。 远的不说,效果也不会在一个家庭友好的报纸打印

至于为什么这是可怕的,我们可以用不明显,聪明的开始(记住,聪明是坏的,聪明的代码是很难维护),而不是在所有的内lambda表达式,缓慢的,脆的设计者所设想的通过设计用例,不可移植的,和不必要

从这些言论,我会说,它不会成为一个文件或支持的行为。



Answer 3:

据我所知,这是一个实现细节。

不过,我认为你可以打赌它不会真正改变。

我只是在VS2012 RC测试,它将按预期工作 - 所以你至少几年安全。



文章来源: Getting names of local variables (and parameters) at run-time through lambda expressions
标签: c# .net lambda