【发布时间】:2016-03-31 16:23:38
【问题描述】:
我有以下 C# 方法:
private static string GetMemberName<T>(Expression<Func<T>> expr)
{
MemberExpression memberExpr = expr.Body as MemberExpression;
if (memberExpr == null)
throw new ArgumentOutOfRangeException("Wrong type of lambda...");
return memberExpr.Member.Name;
}
我可以像这样使用它来打印类级字段、方法参数或本地变量的名称(注意这是 C# 6.0 之前的nameof operator):
private static int _myFieldVar = 62;
private static void DoStuff(int myMethodParam)
{
int myLocalVar = 2;
Debug.Print(GetMemberName(() => myMethodParam)); // prints "myMethodParam"
Debug.Print(GetMemberName(() => myLocalVar)); // prints "myLocalVar"
Debug.Print(GetMemberName(() => _myFieldVar)); // _myFieldVariable
}
现在我想把这段代码转换成VB.NET,所以这里是GetMemberName方法:
Private Function GetMemberName(Of T)(expr As Expression(Of Func(Of T))) As String
Dim memberExpr As MemberExpression = TryCast(expr.Body, MemberExpression)
If memberExpr Is Nothing Then _
Throw New ArgumentOutOfRangeException("Wrong type of lambda...")
Return memberExpr.Member.Name
End Function
但是,当我获得方法参数和局部变量名称时,我注意到不同的结果,即它们都以“$VB$Local_”为前缀:
Private _myFieldVar As Integer = 62
Private Sub DoThis(myMethodParam As Integer)
Dim myLocalVar = 2
Debug.Print(GetMemberName(Function() myMethodParam)) ' prints "$VB$Local_myMethodParam""
Debug.Print(GetMemberName(Function() myLocalVar)) ' prints "$VB$Local_myLocalVar"
Debug.Print(GetMemberName(Function() _myFieldVar)) ' prints "_myFieldVar()"
End Sub
我搜索了“$VB$Local_”并找到了非常相似的this post。但是,我认为我的问题有所不同,因为我没有通过属性获得这种行为。如果我这样称呼:
Debug.Print(GetMemberName(Function() MyProperty))
我得到“我的财产”。此外,我的基本问题是“为什么 C# 和 VB.NET 之间的行为不同,即“$VB$Local_”的含义是什么,为什么在 C# 中不存在”,而那篇文章更关心如何在 VB.NET 中避免这种行为。
【问题讨论】:
-
但是理论上都编译成同一个IL,那为什么会以不同的方式存储呢?为什么
Member.Name在一种语言与另一种语言中的值不同? -
您只是看到 C# 和 VB.NET 编译器用于命名捕获的变量成员的不同策略。是的,VB.NET 编译器将“$VB$Local”作为变量名的前缀。使用 ildasm.exe 很容易看到,注意 _Closure__2-0 类的成员。这是一个纯粹的实现细节,可能会由您的代码公开。
-
是的,重点是本地人(和参数)根本不是调用类的成员,您正在查看的是捕获。
-
@HenkHolterman -- 所以我不想将
expr.Body转换为MemberExpression?在这种情况下,我找不到任何有关访问“捕获”的信息... -
看汉斯的评论,你的成员表达式是指生成类的成员。 VB 编译器可以随意生成。
标签: c# vb.net linq expression-trees c#-to-vb.net