2009-01-16 53 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迫使我们从现在开始思考我们认为的“私人”或“公共”财产 - 因为我们必须根据各个访问者过滤自己。