我正在寻找一种检索变量名的方法,因此我不需要在需要时使用硬编码声明(对于属性名称等):
我几乎不相信这是可能的;也许有人有解决方案。 注意:即使不是变量,属性也是一个动作。
'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
答案在VB或C#中都很受欢迎。
答案 0 :(得分:5)
@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'”。 Rinat的方法利用C#编译器生成的属性名称在表达式new{args}
中生成匿名类型。完整的文章在这里:http://abdullin.com/journal/2008/12/13/how-to-find-out-variable-or-parameter-name-in-c.html
- 编辑 -
进一步阅读Rinat的文章后,也可以通过生成表达式树并浏览树或其包含的IL来完成。基本上,阅读链接的文章!
答案 1 :(得分:5)
哦有一个简单的解决方案,这里使用表达式树就是一个例子,只需在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"
我第一次看到它,这是一个启示! ;)
答案 2 :(得分:3)
所以,你的例子看起来像是:
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
- &gt; "Name"
)。
答案 3 :(得分:2)
那是不可能的。在您的示例中发送给方法的不是变量本身,而只是变量包含的引用的副本。
该方法可以扫描成员变量中存在的所有对象,但只有在变量是类成员时才可行。局部变量不可能达到那种方式,因为它们只存在于堆栈中。此外,如果多个变量中存在相同的引用,则该方法将无法分辨使用哪个变量。
在你的例子中,Name属性返回一个空引用,当然不可能知道它来自何处。
如果变量是值类型,它将被装入堆中的新对象内。由于对盒装对象的唯一引用是发送给方法的对象,并且盒装对象没有引用回原始对象,因此无法确定哪个变量被装箱。