如何通过反射获取静态属性

问题描述 投票:0回答:8

所以这看起来很基本,但我无法让它工作。我有一个对象,我正在使用反射来获取它的公共属性。其中一个属性是静态的,我没有运气得到它。

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

.net reflection static
8个回答
169
投票

或者看看这个...

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...
}

51
投票

这是 C#,但应该可以给你这样的想法:

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

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

(您只需要 OR NonPublic 和 Static)


50
投票

稍微清晰一点...

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

30
投票

好吧,对我来说关键是使用 .FlattenHierarchy BindingFlag。我真的不知道为什么我凭直觉添加它并且它开始工作。所以允许我获取公共实例或静态属性的最终解决方案是:

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

9
投票
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

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


4
投票

只是想为自己澄清这一点,同时使用基于

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 迫使我们从现在开始准确思考什么是“私有”或“公共”属性 - 因为我们必须根据各个访问器来过滤自己。


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


    }
}

-3
投票

尝试这个 C# Reflection 链接。

注意我认为 BindingFlags.Instance 和 BindingFlags.Static 是互斥的。

© www.soinside.com 2019 - 2024. All rights reserved.