Cómo obtener una propiedad estática con Reflection

Así que esto parece bastante básico, pero no puedo hacer que funcione. Tengo un objeto y estoy usando el reflection para acceder a sus propiedades públicas. Una de estas propiedades es estática y no tengo suerte para llegar a ella.

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

El código anterior funciona bien para las propiedades de Instancia Pública, que hasta ahora era todo lo que necesitaba. Supuestamente puedo usar BindingFlags para solicitar otros tipos de propiedades (privadas, estáticas), pero parece que no puedo encontrar la combinación correcta.

 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 

Pero aún así, solicitar cualquier miembro estático no devuelve nada. El reflector .NET puede ver las propiedades estáticas bien, así que claramente me falta algo aquí.

O solo mira esto …

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

Esto es C #, pero debería darle la idea:

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

(usted necesita O No Público y Estático solamente)

Ok, entonces la clave para mí era usar .FlattenHierarchy BindingFlag. Realmente no sé por qué lo agregué por un presentimiento y comenzó a funcionar. Entonces, la solución final que me permite obtener Instancia Pública o Propiedades Estáticas es:

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

Un poco de claridad …

 // 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; 
 myType.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); 

Esto devolverá todas las propiedades estáticas en la clase base estática o en un tipo particular y probablemente también en el niño.

El siguiente parece funcionar para mí.

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

Solo quería aclarar esto por mí mismo, al usar la nueva API de reflexión basada en TypeInfo , donde BindingFlags no está disponible confiablemente (dependiendo del marco de destino).

En la reflexión ‘nueva’, para obtener las propiedades estáticas para un tipo (sin incluir la (s) clase (s) básica (s)) tienes que hacer algo como:

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

Ofrece tanto propiedades de solo lectura como de solo escritura (a pesar de que solo escritura es una idea terrible).

El miembro DeclaredProperties tampoco distingue entre propiedades con acceso público / privado, por lo que para filtrar la visibilidad, debe hacerlo en función del acceso que necesite utilizar. Por ejemplo, suponiendo que la llamada anterior haya regresado, podría hacer:

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

Hay algunos métodos de acceso directo disponibles, pero en última instancia, todos vamos a escribir muchos más métodos de extensión en torno a los métodos / propiedades de consulta de TypeInfo en el futuro. Además, la nueva API nos obliga a pensar a partir de ahora sobre lo que consideramos una propiedad ‘privada’ o ‘pública’, porque debemos filtrarnos a nosotros mismos en función de los usuarios individuales.

Pruebe este enlace de reflexión C # .

Nota: creo que BindingFlags.Instance y BindingFlags.Static son exclusivos.