2009-01-29 116 views
66

我想獲取特定屬性的PropertyInfo。我可以使用:如何獲取特定屬性的PropertyInfo?

foreach(PropertyInfo p in typeof(MyObject).GetProperties()) 
{ 
    if (p.Name == "MyProperty") { return p } 
} 

但是,必須有一種方法做類似

typeof(MyProperty) as PropertyInfo 

東西是嗎?或者我堅持做一個類型不安全的字符串比較?

乾杯。

回答

33

可以使用新的nameof()操作符是在Visual Studio 2015年的C#6部分,可用。更多信息here

爲了您的例子中,你可以使用:

PropertyInfo result = typeof(MyObject).GetProperty(nameof(MyObject.MyProperty)); 

編譯器將nameof(MyObject.MyProperty)轉換爲字符串「myProperty的」,但你獲得的能夠重構屬性名的好處,而不必記住要改變字符串因爲Visual Studio,ReSharper等知道如何重構nameof()值。

10

你可以這樣做:

typeof(MyObject).GetProperty("MyProperty") 

然而,因爲C#沒有一個「符號」式的,沒有什麼,這將有助於你避免使用字符串。順便說一句,你爲什麼稱這種類型不安全?

+32

因爲它沒有在編譯時評估?如果我改變了我的屬性名稱,或者在代碼運行之前我不知道字符串。 – tenpn 2009-01-29 13:22:06

0

反射用於運行時類型評估。所以你的字符串常量不能在編譯時驗證。

+5

這是OP試圖避免的。不知道這是否回答了這個問題。 – nawfal 2013-12-13 11:42:36

+0

關於編譯時間與運行時間以及OP的初衷雖然避免硬編碼字符串的好處仍然似乎是最乾淨的解決方案 - 避免錯別字的可能性,允許更簡單的重構,並使代碼風格更清晰。 – 2014-10-16 14:18:41

120

有一個.NET 3.5的方式與lambda表達式/ Expression不使用字符串...

using System; 
using System.Linq.Expressions; 
using System.Reflection; 

class Foo 
{ 
    public string Bar { get; set; } 
} 
static class Program 
{ 
    static void Main() 
    { 
     PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar); 
    } 
} 
public static class PropertyHelper<T> 
{ 
    public static PropertyInfo GetProperty<TValue>(
     Expression<Func<T, TValue>> selector) 
    { 
     Expression body = selector; 
     if (body is LambdaExpression) 
     { 
      body = ((LambdaExpression)body).Body; 
     } 
     switch (body.NodeType) 
     { 
      case ExpressionType.MemberAccess: 
       return (PropertyInfo)((MemberExpression)body).Member; 
      default: 
       throw new InvalidOperationException(); 
     } 
    } 
} 
+0

很好的解決方案,但不幸的是我沒有使用.NET3.5。仍然,剔! – tenpn 2009-01-29 13:22:41