.net - what - Cómo obtener una propiedad estática con Reflection
what can be done with reflection in c#? (8)
Así que esto parece bastante básico, pero no puedo hacer que funcione. Tengo un objeto y estoy usando el reflejo 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í.
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());
}
}
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)
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...
}
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)
Pruebe este enlace de reflexión C # .
Nota: creo que BindingFlags.Instance y BindingFlags.Static son exclusivos.
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<PropertyInfo> 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.
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.