获取变量(没有硬编码)的名字吗?(Get variable (not hard-coded) nam

2019-08-04 01:43发布

我正在寻找一种方法来检索变量名,这样在需要时(对于属性名称等)我没有使用硬编码的声明:

我简直不敢相信这是可能的; 也许有人有一个解决方案。 注意:即使是变量,属性也将是一招。

'Pseudo:
Module Module1

    Sub Main()
        Dim variable = "asdf"
        Dim contact As New Contact

        Dim v1 = GetVariableName(variable) 'returns variable
        Dim v2 = GetVariableName(contact.Name) 'returns Name

    End Sub

    Class Contact
        Public ReadOnly Property Name()
            Get
                Return Nothing
            End Get
        End Property
    End Class

    Public Function GetVariableName(variable As Object) As String
        ':}
    End Function

End Module

答案是welcommed在任何VB或C#。

Answer 1:

哦,有一个简单的解决方案,在这里使用表达式树就是一个例子,只是适应C#您的需求

string GetPropertyName<T>(Expression<Func<T>> property)
{
    MemberExpression ex = (MemberExpression)property.Body;
    string propertyName = ex.Member.Name;
    return propertyName;
}

现在你可以做

String example = null;
String propertyName = GetPropertyName(()=>example.Length);
//propertyName == "Length"

第一次我已经看到了,这是一个启示! ;)



Answer 2:

@Abraham Pinzur; 下面的文章中进一步链接,您链接到提供该片段:

static void Main(string[] args)
{
Console.WriteLine("Name is '{0}'", GetName(new {args}));
Console.ReadLine();
}

static string GetName<T>(T item) where T : class
{
var properties = typeof(T).GetProperties();
return properties[0].Name;
}

这确实产生“名称是‘ARGS’”。 里纳特的方法利用由C#编译器生成,以产生在表达式匿名类型属性名new{args} 完整的文章是在这里: http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html

- 编辑 -

还具有其他读入的Rinat的文章,这也可以通过产生一个表达式树和浏览无论是树,或者它包含的IL完成。 基本上,阅读链接的文章!



Answer 3:

的Rinat阿卜杜林是做这样的事情通过从一个匿名方法(或lambda表达式)解析IL。 他的完整的代码是在这里 。

所以,你的例子看起来像:

class Program
{
    static void Main (string[] args)
    {
        var variable = "asdf";

        var v1 = GetVariableName(() => variable);  // returns "variable"
    }

    static string GetVariableName (Func<object> variable)
    {   // Again, credit to Mr. Abdullin ...
        var il = variable.Method.GetMethodBody().GetILAsByteArray();
        var fieldHandle = BitConverter.ToInt32(il,2);
        var field = variable.Target.GetType()
                .Module.ResolveField(fieldHandle);
        return field.Name;
    }
}

然而,这并不直接延伸到你的第二个案例( contact.Name - > "Name" )。



Answer 4:

这是不可能的。 什么是发送到方法的例子是不是变量本身,而只是一个变量包含引用的副本。

该方法可以扫描存在于构件变量之间的参考的所有对象,但是这将仅是可行的,如果该变量是一个类的成员。 局部变量是不可能的,因为他们只在堆栈上存在到达的方式。 此外,如果相同的一个以上的变量存在,此方法将无法告诉它们中的使用。

在你的榜样Name属性返回空引用,这当然是不可能知道那是从哪里来的。

如果变量是值类型,它将获得盒装堆上一个新的对象内。 至于装箱对象的唯一引用是发送给该方法的一个,并且盒装对象没有参考回到原来的,没有办法告诉哪个变量被装箱。



文章来源: Get variable (not hard-coded) name?