2009-01-16 16 views
83

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.Cómo obtener una propiedad estática con Reflection

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

+0

Esto es realmente muy similar a esto: http://stackoverflow.com/questions/392122/in-c-how-can-i-tell-if-a-property-is-static-net-cf -2-0 – ctacke

+0

Bueno, es similar, ya que ambos usan BindingFlags. Estoy buscando una combinación específica de BindingFlags que me permita obtener miembros públicos, ya sean estáticos o de instancia. –

Respuesta

26

Ok, la clave para mí fue utilizar .FlattenHierarchy BindingFlag. Realmente no sé por qué lo agregué por un presentimiento y comenzó a funcionar. Así que la solución final que permite que consiga 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) 
36

Este es C#, pero debe darle la idea:

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

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

(lo necesita o no pública y sólo estático)

+3

En mi caso, usar solo estas dos banderas no funcionó. También tuve que usar el indicador .FlattenHierarchy. –

+1

@CoreyDownie estuvo de acuerdo. 'BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy' fue lo único que funcionó para mí. –

1

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


    } 
} 
97

O simplemente 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... 
} 
+0

¿A qué variables corresponden estos dos valores nulos? ¿Cómo escribirías esto usando argumentos con nombre, si es posible? Gracias. –

+0

Para clase interna estática? – Kiquenet

+0

Esta es la mejor opción, en mi opinión, debe seleccionarse como la respuesta. – c0y0teX

5
myType.GetProperties(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy); 

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

24

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; 
+0

'BindingFlags.Instance | BindingFlags.Static' lo resolvió por mí. – LosManos

1

Sólo quería aclarar esto para mí mismo, durante el uso de la nueva API de reflexión a partir de TypeInfo - donde BindingFlags no está disponible de forma fiable (en función del marco de destino).

En la 'nueva' reflexión, para obtener las propiedades estáticas para un tipo (sin incluir la clase base (es)) que tiene que hacer algo como:

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

une la zona de sólo lectura o escritura -únicamente propiedades (a pesar de que solo escritura sea una idea terrible).

El miembro DeclaredProperties, también no distingue entre propiedades con accesadores públicos/privados, por lo que para filtrar la visibilidad, debe hacerlo en función del acceso que necesita utilizar. MI.g - asumiendo la llamada anterior ha vuelto, que podría hacer:

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

Hay algunos métodos de acceso directo disponible - pero al final todos vamos a estar escribiendo mucho más métodos de extensión en torno a los métodos de consulta TypeInfo/propiedades 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.

Cuestiones relacionadas