2009-01-16 47 views
83

所以這似乎很基本,但我不能得到它的工作。我有一個對象,我使用反射來獲取它的公共屬性。其中一個屬性是靜態的,我沒有運氣。如何獲得靜態屬性與反射

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo 
    Return obj.GetType.GetProperty(propName) 

End Function 

上面的代碼適用於公共實例屬性,直到現在,我所需要的都是上述代碼。據我可以使用BindingFlags來請求其他類型的屬性(私人,靜態),但我似乎無法找到正確的組合。

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo 
    Return obj.GetType.GetProperty(propName, Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.Public) 

End Function 

但仍然請求任何靜態成員不返回任何內容。 .NET反射器可以看到靜態屬性就好了,所以很明顯我在這裏丟失了一些東西。

+0

這是真的,非常類似於此: http://stackoverflow.com/questions/392122/in-c-how-can-i-tell-if-a-property-is-static-net-cf -2-0 – ctacke 2009-01-16 18:42:24

+0

那麼它們都使用BindingFlags。我正在尋找BindingFlags的特定組合,這將允許我獲得Public成員,無論是Static還是Instance。 – 2009-01-16 19:19:02

回答

26

好的,所以我的關鍵是使用.FlattenHierarchy BindingFlag。我不知道爲什麼我只是在預感上加上它,並開始工作。因此,最終的解決方案,可以讓我獲得公共實例或靜態屬性是:

obj.GetType.GetProperty(propName, Reflection.BindingFlags.Public _ 
    Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or _ 
    Reflection.BindingFlags.FlattenHierarchy) 
36

這是C#,但應該給你的想法:

public static void Main() { 
    typeof(Program).GetProperty("GetMe", BindingFlags.NonPublic | BindingFlags.Static); 
} 

private static int GetMe { 
    get { return 0; } 
} 

(你需要或非公開,只有靜態)

+3

在我的情況下,只使用這兩個標誌不起作用。我還必須使用.FlattenHierarchy標誌。 – 2011-08-16 16:47:43

+1

@CoreyDownie同意。 `BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy`是唯一對我有用的東西。 – 2012-05-02 15:47:22

1

以下似乎適用於我。

using System; 
using System.Reflection; 

public class ReflectStatic 
{ 
    private static int SomeNumber {get; set;} 
    public static object SomeReference {get; set;} 
    static ReflectStatic() 
    { 
     SomeReference = new object(); 
     Console.WriteLine(SomeReference.GetHashCode()); 
    } 
} 

public class Program 
{ 
    public static void Main() 
    { 
     var rs = new ReflectStatic(); 
     var pi = rs.GetType().GetProperty("SomeReference", BindingFlags.Static | BindingFlags.Public); 
     if(pi == null) { Console.WriteLine("Null!"); Environment.Exit(0);} 
     Console.WriteLine(pi.GetValue(rs, null).GetHashCode()); 


    } 
} 
97

或者單看這...

Type type = typeof(MyClass); // MyClass is static class with static properties 
foreach (var p in type.GetProperties()) 
{ 
    var v = p.GetValue(null, null); // static classes cannot be instanced, so use null... 
} 
5
myType.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); 

這將在靜態基地返回所有的靜態屬性班級或特定類型,也可能是孩子。

24

一點點清晰......

// Get a PropertyInfo of specific property type(T).GetProperty(....) 
PropertyInfo propertyInfo; 
propertyInfo = typeof(TypeWithTheStaticProperty) 
    .GetProperty("NameOfStaticProperty", BindingFlags.Public | BindingFlags.Static); 

// Use the PropertyInfo to retrieve the value from the type by not passing in an instance 
object value = propertyInfo.GetValue(null, null); 

// Cast the value to the desired type 
ExpectedType typedValue = (ExpectedType) value; 
1

只是想澄清這一點我自己,而使用基於TypeInfo新的反射API - 其中BindingFlags不可用可靠(取決於目標框架)。

在「新」反射,以得到一個類型的靜態屬性(不包括基類(ES)),你必須做一些事情,如:

IEnumerable<PropertyInfo> props = 
    type.GetTypeInfo().DeclaredProperties.Where(p => 
    (p.GetMethod != null && p.GetMethod.IsStatic) || 
    (p.SetMethod != null && p.SetMethod.IsStatic)); 

迎合兩個只讀或寫 - 僅屬性(儘管只寫是一個可怕的想法)。

DeclaredProperties成員也不能區分具有公共/私人訪問器的屬性 - 因此,要過濾可見性,則需要根據您需要使用的訪問器來執行此操作。 E.摹 - 假設上面的調用返回,你可以這樣做:

var publicStaticReadable = props.Where(p => p.GetMethod != null && p.GetMethod.IsPublic); 

有一些快捷鍵可用的方法 - 但最終我們都將會寫作圍繞在TypeInfo查詢方法/屬性有更多的擴展方法未來。此外,新的API迫使我們從現在開始思考我們認爲的「私人」或「公共」財產 - 因爲我們必須根據各個訪問者過濾自己。