如何从C#(2.0)中的属性获取属性的名称

我知道我可以有一个属性,但这比我想去的工作更多……而且不够通用。

我想做点什么

class Whotsit { private string testProp = "thingy"; public string TestProp { get { return testProp; } set { testProp = value; } } } ... Whotsit whotsit = new Whotsit(); string value = GetName(whotsit.TestProp); //precise syntax up for grabs.. 

在哪里我期望价值等于“TestProp”

但我不能为我的生活找到正确的reflection方法来编写GetName方法…

编辑:我为什么要这样做? 我有一个类来存储从’name’,’value’表中读取的设置。 这由基于reflection的通用方法填充。 我非常想反过来写…

 ///  /// Populates an object from a datatable where the rows have columns called NameField and ValueField. /// If the property with the 'name' exists, and is not read-only, it is populated from the /// valueField. Any other columns in the dataTable are ignored. If there is no property called /// nameField it is ignored. Any properties of the object not found in the data table retain their /// original values. ///  /// Type of the object to be populated. /// The object to be populated /// 'name, 'value' Data table to populate the object from. /// Field name of the 'name' field'. /// Field name of the 'value' field. /// Setting to control conversions - eg nulls as empty strings. public static void PopulateFromNameValueDataTable (T toBePopulated, System.Data.DataTable dataTable, string nameField, string valueField, PopulateOptions options) { Type type = typeof(T); bool nullStringsAsEmptyString = options == PopulateOptions.NullStringsAsEmptyString; foreach (DataRow dataRow in dataTable.Rows) { string name = dataRow[nameField].ToString(); System.Reflection.PropertyInfo property = type.GetProperty(name); object value = dataRow[valueField]; if (property != null) { Type propertyType = property.PropertyType; if (nullStringsAsEmptyString && (propertyType == typeof(String))) { value = TypeHelper.EmptyStringIfNull(value); } else { value = TypeHelper.DefaultIfNull(value, propertyType); } property.SetValue(toBePopulated, System.Convert.ChangeType(value, propertyType), null); } } } 

进一步编辑:我只是在代码中,有一个Whotsit实例,我想得到’TestProp’属性的文本字符串。 我知道这似乎有点奇怪,我可以使用文字“TestProp” – 或者在我的类的情况下使用数据表函数我将在PropertyInfos的foreach循环中。 我只是好奇而已…

原始代码有字符串常量,我发现它很笨拙。

不,没有什么可以做的。 表达式whotsit.TestProp将评估该属性。 你想要的是神秘的“infoof”运算符:

 // I wish... MemberInfo member = infoof(whotsit.TestProp); 

实际上,您只能使用reflection来按名称获取属性 – 而不是代码。 (当然,或者获取所有属性。虽然它仍然无法帮助您处理样本。)

一种替代方法是使用表达式树:

 Expression> = () => whotsit.TestProp; 

然后检查表达式树以获取属性。

如果这些都没有帮助,也许你可以告诉我们更多你想要这个function的原因?

它是可能的(没有reflection)但只有最新的C#3.0

快速而且非常脏

 class Program { static void Main() { string propertyName = GetName(() => AppDomain.CurrentDomain); Console.WriteLine(propertyName); // prints "CurrentDomain" Console.ReadLine(); } public static string GetName(Expression> property) { return property.Body.ToString().Split('.').Last(); } } 

更新:我刚才意识到Jon Skeet (任何人都感到惊讶?:)已经涵盖了这种可能性,但我会在这里保留我的答案,以防万一有人对一些例子感兴趣。

我不认为这是可能的,唯一的方法是迭代属性:

 class TestClass { private string _field; public string MyProperty { get { return _field; } } } class Program { static void Main(string[] args) { TestClass test = new TestClass(); PropertyInfo[] info = test.GetType().GetProperties(); foreach(PropertyInfo i in info) Console.WriteLine(i.Name); Console.Read(); } } 

Kpollack,你在之前的评论中说过:

它仍然不会让我能够从它的实例获取属性的名称。

这让我相信你以某种方式引用了一个属性。 你是怎么得到这个参考的? 它的类型是什么? 你能提供一个代码示例吗? 如果它是PropertyInfo对象,那么您已经拥有了所需的东西; 因为事实并非如此,我们正在处理其他事情,而且我很想知道你必须要做什么。

PS原谅我看似迟钝:它很早,我没有足够的咖啡,我没有在我面前的IDE。 : – /

你想要做的是不可能的。 使用reflection你可以:

  • 从它的字符串名称中获取属性,字段或方法的详细信息。
  • 获取给定类型的所有属性,字段或方法的列表。

调用时,GetName方法将传递一个字符串。 GetMethod将知道字符串但不保留源属性元数据。

出于兴趣,你为什么要这样做?

仅供参考,我试图将其序列化以查看是否偶然包含了属性名称,但没有运气。

下面的非工作代码:

 Whotsit w = new Whotsit(); XmlSerializer xs = new XmlSerializer(w.TestProp.GetType()); TextWriter sw = new StreamWriter(@"c:\TestProp.xml"); xs.Serialize(sw, w.TestProp); sw.Close(); 

Type类上的GetProperties将为您提供该类型的属性列表。

 Type t = whotsit.GetType(); PropertyInfo[] pis = t.GetProperties();