ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

这真的非常类似于:stackoverflow.com/questions/392122/…
嗯,它们都使用 BindingFlags 是相似的。我正在寻找一种特定的 BindingFlags 组合,它可以让我获得公共成员,无论是静态成员还是实例。

E
Ernest

或者只是看看这个...

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

这两个空值对应于哪些变量?如果可能的话,你将如何使用命名参数来编写它?谢谢。
对于内部静态类?
这是最好的选择,我认为应该选择它作为答案。
p.GetValue(null); 也可以。第二个 null 不是必需的。
看起来很棒。目标是根据名称参数获取属性 - 我认为我不想遍历任何属性来实现这一目标。
e
earlNameless

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

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

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

(您只需要 OR NonPublic 和 Static)


就我而言,仅使用这两个标志是行不通的。我还必须使用 .FlattenHierarchy 标志。
@CoreyDownie 同意。 BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy 是唯一对我有用的东西。
L
Lee Taylor

有点清晰...

// 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 为我解决了这个问题。
C
Corey Downie

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

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

J
Jérôme Verstrynge
myType.GetProperties(BindingFlags.Public | BindingFlags.Static |  BindingFlags.FlattenHierarchy);

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


A
Andras Zoltan

只是想为自己澄清这一点,同时使用基于 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 迫使我们从现在开始准确地思考我们所认为的“私有”或“公共”属性——因为我们必须根据个人访问者过滤自己。


V
Vyas Bharghava

以下似乎对我有用。

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


    }
}

K
Ken Henderson

试试这个 C# Reflection 链接。

请注意,我认为 BindingFlags.Instance and BindingFlags.Static 是排他性的。


是的,我希望情况并非如此,因为我希望我能够获得任何公共实例或静态。
它们不是排他性的。我刚刚测试了它。