2008-10-26 11 views
26

¿Cómo obtengo el valor de un objeto MemberInfo? .Name devuelve el nombre de la variable, pero necesito el valor.¿Cómo obtengo el valor de MemberInfo?

Creo que puedes hacer esto con FieldInfo pero no tengo un fragmento, si sabes cómo hacerlo, ¿puedes proporcionar un fragmento?

Gracias!

Respuesta

32

He aquí un ejemplo para los campos, usando FieldInfo.GetValue:

using System; 
using System.Reflection; 

public class Test 
{ 
    // public just for the sake of a short example. 
    public int x; 

    static void Main() 
    { 
     FieldInfo field = typeof(Test).GetField("x"); 
     Test t = new Test(); 
     t.x = 10; 

     Console.WriteLine(field.GetValue(t)); 
    } 
} 

código similar funcionará para el inmueble con PropertyInfo.GetValue() - aunque hay también tiene que pasar los valores de los parámetros a las propiedades. (No habrá ninguna para las propiedades "normales" de C#, pero los indexadores de C# también cuentan como propiedades en lo que respecta al marco). Para los métodos, deberá llamar al Invoke si desea llamar al método y usar el valor de retorno

+2

gracias Jon - podría dar un ejemplo a partir de un objeto MemberInfo sin embargo? –

+1

¿De qué tipo? MemberInfos puede ser propiedades, campos, métodos, eventos u otros tipos. No puedes tratarlos todos de la misma manera. ¿Cuál sería el "valor" de un tipo anidado, por ejemplo? Tal vez deberías decirnos más sobre tu problema. –

+1

muy mal GetValue/SetValue no era una interfaz con la que se pudiera comparar. –

10

respuesta de Jon es ideal - sólo una observación: como parte del diseño general, lo haría:

  1. general evitar que refleja contra miembros no públicos
  2. evitar tener campos públicos (casi siempre)

El resultado de estos dos es que general sólo es necesario para reflejar contra propiedades públicas (que no debe llamar a métodos a menos que sepas lo que hacen; los captadores de propiedad son esperado ser idempotente [lazy loading beside]). Entonces, para un PropertyInfo esto es solo prop.GetValue(obj, null);.

En realidad, soy un gran fan de System.ComponentModel, por lo que estaría tentado a usar:

foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) 
    { 
     Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj)); 
    } 

o para una propiedad específica:

PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["SomeProperty"]; 
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj)); 

Una ventaja de System.ComponentModel es que se trabajará con modelos de datos abstraídos, como por ejemplo cómo DataView expone columnas como propiedades virtuales; También hay otros trucos (como performance tricks).

+0

Esto resultó muy efectivo para mi escenario ya que tengo para trabajar con propiedades y llamar a GetField() en el objeto que sigue devolviendo un nulo. Gracias por esto. – MikeMalter

+0

ah, ahí está ... Solo pude recordar vagamente que existía otro medio fuera del espacio de nombres de Reflection: 'MemberInfo' y' PropertyInfo' .. 'PropertyDescriptor' cumple bien mi propósito actual ya que estoy usando' INotifyPropertyChanged' en mi ejemplo... –

12

Aunque en general estoy de acuerdo con el punto de Marc sobre no reflejar campos, hay ocasiones en que es necesario. Si desea reflejar un miembro y no le importa si es un campo o una propiedad, puede usar este método de extensión para obtener el valor (si desea el tipo en lugar del valor, consulte la respuesta de nawful al this question):

public static object GetValue(this MemberInfo memberInfo, object forObject) 
    { 
     switch (memberInfo.MemberType) 
     { 
      case MemberTypes.Field: 
       return ((FieldInfo)memberInfo).GetValue(forObject); 
      case MemberTypes.Property: 
       return ((PropertyInfo)memberInfo).GetValue(forObject); 
      default: 
       throw new NotImplementedException(); 
     } 
    } 
Cuestiones relacionadas