所以这看起来很基本,但我无法让它工作。我有一个对象,我正在使用反射来获取它的公共属性。这些属性之一是静态的,我没有运气。
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 反射器可以很好地看到静态属性,所以很明显我在这里遗漏了一些东西。
或者只是看看这个...
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...
}
这是 C#,但应该给你的想法:
public static void Main() {
typeof(Program).GetProperty("GetMe", BindingFlags.NonPublic | BindingFlags.Static);
}
private static int GetMe {
get { return 0; }
}
(您只需要 OR NonPublic 和 Static)
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;
BindingFlags.Instance | BindingFlags.Static
为我解决了这个问题。
好的,所以对我来说关键是使用 .FlattenHierarchy BindingFlag。我真的不知道为什么我只是凭直觉添加它并开始工作。因此,让我获得公共实例或静态属性的最终解决方案是:
obj.GetType.GetProperty(propName, Reflection.BindingFlags.Public _
Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.Instance Or _
Reflection.BindingFlags.FlattenHierarchy)
myType.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
这将返回静态基类或特定类型中的所有静态属性,也可能返回子类。
只是想为自己澄清这一点,同时使用基于 TypeInfo
的新反射 API - 其中 BindingFlags
不可靠(取决于目标框架)。
在“新”反射中,要获取类型(不包括基类)的静态属性,您必须执行以下操作:
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 迫使我们从现在开始准确地思考我们所认为的“私有”或“公共”属性——因为我们必须根据个人访问者过滤自己。
以下似乎对我有用。
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());
}
}
试试这个 C# Reflection 链接。
请注意,我认为 BindingFlags.Instance and BindingFlags.Static 是排他性的。
p.GetValue(null);
也可以。第二个null
不是必需的。