2009-06-12 16 views
19
public class Foo 
{ 
    public string Bar {get; set;} 
} 

¿Cómo obtengo el valor de Bar, una propiedad de cadena, a través de la reflexión? El siguiente código lanzar una excepción si el tipo es un PropertyInfo System.String¿Cómo puedo obtener el valor de una propiedad de cadena mediante Reflection?

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

foreach(var property in f.GetType().GetProperties()) 
{ 
object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type 
} 

Parece que mi problema es que la propiedad es un tipo de controlador paso a paso, con un System.String.

Además, ¿cómo puedo saber si la propiedad es un indexador?

+1

funciona bien aquí ... ¿está pasando algo más? – womp

+0

parece que no está publicando suficiente código contextual? – Firoso

+0

Sí. El depurador dice que el tipo subyacente es cadena, pero sospecho que está ocurriendo algo más. – Alan

Respuesta

42

Usted sólo puede obtener la propiedad por su nombre:

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

var barProperty = f.GetType().GetProperty("Bar"); 
string s = barProperty.GetValue(f,null) as string; 

En cuanto al seguimiento pregunta: indexadores siempre serán nombrados punto y tener argumentos en el getter Así

Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

var barProperty = f.GetType().GetProperty("Item"); 
if (barProperty.GetGetMethod().GetParameters().Length>0) 
{ 
    object value = barProperty.GetValue(f,new []{1/* indexer value(s)*/}); 
} 
+1

Eso es inexacto. Item es el nombre predeterminado para los indexadores, pero cualquiera puede usar un IndererNameAttribute en la propiedad del indexador para cambiar eso. Debe buscar DefaultMemberAttribute en el tipo para obtener el nombre real del indexador. –

+1

¡Estaba completamente inconsciente del atributo IndexerName! Gracias. Puede encontrar más información aquí: http://bartdesmet.net/blogs/bart/archive/2006/09/09/4408.aspx Gracias Jb Evain. – Jake

+0

Puede en VB .. –

3
Foo f = new Foo(); 
f.Bar = "Jon Skeet is god."; 

foreach(var property in f.GetType().GetProperties()) 
{ 
    if(property.Name != "Bar") 
    { 
     continue; 
    } 
    object o = property.GetValue(f,null); //throws exception TargetParameterCountException for String type 
} 

Y aquí es para el seguimiento:

class Test 
{ 
    public class Foo 
    { 
     Dictionary<string, int> data =new Dictionary<string,int>(); 
     public int this[string index] 
     { 
      get { return data[index]; } 
      set { data[index] = value; } 
     } 

     public Foo() 
     { 
      data["a"] = 1; 
      data["b"] = 2; 
     } 
    } 

    public Test() 
    { 
     var foo = new Foo(); 
     var property = foo.GetType().GetProperty("Item"); 
     var value = (int)property.GetValue(foo, new object[] { "a" }); 
     int i = 0; 
    } 
} 
+0

Según los demás comentarios, deberá cambiar el valor nulo en obtener el valor del indexador adecuado. –

5

no podía reproducir el problema. ¿Estás seguro de que no estás tratando de hacer esto en algún objeto con propiedades de indexador? En ese caso, el error que experimente se generará al procesar la propiedad Item. También, usted puede hacer esto:


public static T GetPropertyValue<T>(object o, string propertyName) 
{ 
     return (T)o.GetType().GetProperty(propertyName).GetValue(o, null); 
} 

...somewhere else in your code... 
GetPropertyValue<string>(f, "Bar"); 
+0

Sí, ese es el problema. – Alan

3
Foo f = new Foo(); 
f.Bar = "x"; 

string value = (string)f.GetType().GetProperty("Bar").GetValue(f, null); 
4
var val = f.GetType().GetProperty("Bar").GetValue(f, null); 
1
PropertyInfo propInfo = f.GetType().GetProperty("Bar"); 
object[] obRetVal = new Object[0]; 
string bar = propInfo.GetValue(f,obRetVal) as string; 
+0

¿para qué es exactamente el voto a favor? este código funciona como se esperaba –

+0

No tengo idea. Algunas personas votan para votar. – Alan

0

la getValue con el objeto y nula funcionó muy bien para mí. Gracias por las publicaciones.

Contexto: Retransmisión de todas las propiedades en un modelo MVC para los nuevos empleados y la determinación de su forma de valores de publicación:

newhire => el modelo, con muchas propiedades, cuyos valores a un formulario que quiero escribir de forma individual a un conjunto de registros de la base

foreach(var propertyValue in newHire.GetProperties()) 
{ 
string propName = propertyValue.Name; 

string postedValue = newHire.GetType().GetProperty(propName).GetValue(newHire, null).ToString(); 

} 
1

Su fácil de obtener valor de la propiedad de cualquier objeto por el método de utilización de extensión como:

public static class Helper 
    { 
     public static object GetPropertyValue(this object T, string PropName) 
     { 
      return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T, null); 
     } 
    } 

Uso es:

Foo f = new Foo(); 
f.Bar = "x"; 
var balbal = f.GetPropertyValue("Bar"); 
+0

Gracias a Elvis esto se puede modificar para: 'devolver T.GetType(). GetProperty (PropName). GetValue (T, null);'. https://blogs.msdn.microsoft.com/jerrynixon/2014/02/26/at-last-c-isgetget-sometimes-called-the-safe-navigation-operator/ – JohnLBevan

Cuestiones relacionadas