ChatGPT解决这个技术问题 Extra ChatGPT

How to get a Static property with Reflection

So this seems pretty basic but I can't get it to work. I have an Object, and I am using reflection to get to it's public properties. One of these properties is static and I'm having no luck getting to it.

Public Function GetProp(ByRef obj As Object, ByVal propName as String) as PropertyInfo
    Return obj.GetType.GetProperty(propName)

End Function

The above code works fine for Public Instance properties, which up until now is all that I have needed. Supposedly I can use BindingFlags to request other types of properties (private, static), but I can't seem to find the right combination.

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

But still, requesting any Static members return nothing. .NET reflector can see the static properties just fine, so clearly I am missing something here.

This is really, really similar to this: stackoverflow.com/questions/392122/…
Well it's similar in that they both use BindingFlags. I am looking for a specific combination of BindingFlags that will allow me to get Public members, be they Static or Instance.

E
Ernest

Or just look at this...

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

Which variables do these two nulls correspond to? How would you write this using named arguments, if it is possible? Thanks.
For internal static class ?
This is the best option, in my opinion it should be selected as the answer.
p.GetValue(null); works too. The second null is not required.
Looks great. The goal was to get the property based on a name argument - I don't think I would want to loop over ever property to achieve that.
e
earlNameless

This is C#, but should give you the idea:

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

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

(you need to OR NonPublic and Static only)


In my case, using only these two flags did not work. I had to also use the .FlattenHierarchy flag.
@CoreyDownie agreed. BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy was the only thing that worked for me.
L
Lee Taylor

A little clarity...

// 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 solved it for me.
C
Corey Downie

Ok so the key for me was to use the .FlattenHierarchy BindingFlag. I don't really know why I just added it on a hunch and it started working. So the final solution that allows me to get Public Instance or Static Properties is:

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

This will return all static properties in static base class or a particular type and probably the child as well.


A
Andras Zoltan

Just wanted to clarify this for myself, while using the new reflection API based on TypeInfo - where BindingFlags is not available reliably (depending on target framework).

In the 'new' reflection, to get the static properties for a type (not including base class(es)) you have to do something like:

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

Caters for both read-only or write-only properties (despite write-only being a terrible idea).

The DeclaredProperties member, too doesn't distinguish between properties with public/private accessors - so to filter around visibility, you then need to do it based on the accessor you need to use. E.g - assuming the above call has returned, you could do:

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

There are some shortcut methods available - but ultimately we're all going to be writing a lot more extension methods around the TypeInfo query methods/properties in the future. Also, the new API forces us to think about exactly what we think of as a 'private' or 'public' property from now on - because we must filter ourselves based on individual accessors.


V
Vyas Bharghava

The below seems to work for me.

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

Try this C# Reflection link.

Note I think that BindingFlags.Instance and BindingFlags.Static are exclusive.


Yeah I am hoping that is not the case, because what I want i to be able to get any Public Instance or Static.
They are not exclusive. I just tested it.