How to get a Static property with Reflection

.NetReflectionStatic

.Net Problem Overview


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.

.Net Solutions


Solution 1 - .Net

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

Solution 2 - .Net

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)

Solution 3 - .Net

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;

Solution 4 - .Net

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)

Solution 5 - .Net

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.

Solution 6 - .Net

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.

Solution 7 - .Net

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

		
	}
}

Solution 8 - .Net

Try this C# Reflection link.

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCorey DownieView Question on Stackoverflow
Solution 1 - .NetErnestView Answer on Stackoverflow
Solution 2 - .NetearlNamelessView Answer on Stackoverflow
Solution 3 - .NetGeorgeView Answer on Stackoverflow
Solution 4 - .NetCorey DownieView Answer on Stackoverflow
Solution 5 - .NetIgorView Answer on Stackoverflow
Solution 6 - .NetAndras ZoltanView Answer on Stackoverflow
Solution 7 - .NetVyas BharghavaView Answer on Stackoverflow
Solution 8 - .NetKen HendersonView Answer on Stackoverflow