如何使用反射获得静态属性

这看起来很简单,但我不能让它工作。我有一个 Object,我使用反射来获得它的公共属性。这些属性中有一个是静态的,我没法找到它。

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 反射器可以很好地看到静态属性,所以很明显我在这里遗漏了一些东西。

131916 次浏览

这是 C # ,但应该会给你一些启示:

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


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

(只需要 OR 非公开和静态)

试试这个 C # 反射链接。

注意,我认为 BindingFlags.Instance 和 BindingFlags.Static是独占的。

下面的内容似乎对我有用。

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());




}
}

所以对我来说,关键是使用。层次结构绑定标志。我也不知道为什么我凭直觉加了这个然后就开始起作用了。所以允许我获得公共实例或静态属性的最终解决方案是:

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

或者看看这个。

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...
}
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

这将返回静态基类或特定类型中的所有静态属性,可能还包括子类。

说清楚一点。

// 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;

只是想为自己澄清这一点,同时使用基于 TypeInfo的新反射 API-其中 BindingFlags不可靠(取决于目标框架)。

在“ new”反射中,要获取类型(不包括基类)的静态属性,您必须执行以下操作:

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

同时满足只读或只写属性(尽管只写是一个糟糕的想法)。

DeclaredProperties成员也不区分具有公共/私有访问器的属性-因此,为了根据可见性进行筛选,需要根据需要使用的访问器进行筛选。例如,假设上述电话已经回复,你可以:

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

有一些可用的快捷方法——但是最终我们都将围绕 TypeInfo查询方法/属性编写更多的扩展方法。此外,新的 API 迫使我们从现在开始考虑到底什么是“私有”或“公共”属性——因为我们必须根据各个访问器对自己进行过滤。