2012-04-23 31 views
44

Lo que intento hacer es establecer el valor de la propiedad en una clase utilizando una cadena. Por ejemplo, mi clase tiene las siguientes propiedades:C# setting/obtención de las propiedades de la clase por nombre de cadena

myClass.Name 
myClass.Address 
myClass.PhoneNumber 
myClass.FaxNumber 

Todos los campos son de tipo cadena, así que sé de antemano que siempre es una cadena. Ahora quiero poder establecer las propiedades usando una cadena como lo haría con el objeto DataSet. Algo como esto:

myClass["Name"] = "John" 
myClass["Address"] = "1112 River St., Boulder, CO" 

Idealmente Quiero simplemente asignar una variable y luego establecer la propiedad utilizando ese nombre de la cadena de la variable

string propName = "Name" 
myClass[propName] = "John" 

que estaba leyendo acerca de la reflexión y tal vez es la manera de hacerlo pero no estoy seguro de cómo configurarlo manteniendo el acceso a la propiedad intacto en la clase. Quiero seguir siendo capaz de usar

myClass.Name = "John" 

Cualquier código de ejemplo sería realmente genial.

+0

Posible duplicado de http://stackoverflow.com/questions/1089123/setting-a-property-by-reflection-with-a-string-value – Thomas

+0

Mira eso también: http: // stackoverflow. com/questions/279374/how-do-i-use-net-reflection-to-search-for-a-property-by-name-ignoring-case – MarcinJuraszek

+0

Recuerde que la reflexión es lenta. Si el rendimiento importa, no es recomendable. –

Respuesta

61

Puede añadir una propiedad indexador, un pseudocódigo :

public class MyClass 
{ 
    public object this[string propertyName] 
    { 
     get{ 
      // probably faster without reflection: 
      // like: return Properties.Settings.Default.PropertyValues[propertyName] 
      // instead of the following 
      Type myType = typeof(MyClass);     
      PropertyInfo myPropInfo = myType.GetProperty(propertyName); 
      return myPropInfo.GetValue(this, null); 
     } 
     set{ 
      Type myType = typeof(MyClass);     
      PropertyInfo myPropInfo = myType.GetProperty(propertyName); 
      myPropInfo.SetValue(this, value, null); 

     } 

    } 
} 
+1

Creo que debería eliminar '" 'en' GetProperty ("propertyName") 'y debe usar' SetValue' en 'set' parte – Marco

+0

@Marco: recién hecho :) – Tigran

+0

Muy elegante. Gracias. – Patratacus

-2

puede ser algo como esto?

public class PropertyExample 
{ 
    private readonly Dictionary<string, string> _properties; 

    public string FirstName 
    { 
     get { return _properties["FirstName"]; } 
     set { _properties["FirstName"] = value; } 
    } 

    public string LastName 
    { 
     get { return _properties["LastName"]; } 
     set { _properties["LastName"] = value; } 
    } 
    public string this[string propertyName] 
    { 
     get { return _properties[propertyName]; } 
     set { _properties[propertyName] = value; } 
    } 

    public PropertyExample() 
    { 
     _properties = new Dictionary<string, string>(); 
    } 
} 
+0

También tendrías que completar el diccionario en el constructor para que funcione. –

+0

Sí, es solo una proposición para una implementación posterior – Deitro

+0

Entonces, ¿qué pasa si los valores reales de las propiedades son de tipos diferentes? –

1

Se puede añadir un controlador paso a paso a su clase y el uso reflexión para ases las propiedades:

using System.Reflection; 

public class MyClass { 

    public object this[string name] 
    { 
     get 
     { 
      var properties = typeof(MyClass) 
        .GetProperties(BindingFlags.Public | BindingFlags.Instance); 

      foreach (var property in properties) 
      { 
       if (property.Name == name && property.CanRead) 
        return property.GetValue(this, null); 
      } 

      throw new ArgumentException("Can't find property"); 

     } 
     set { 
      return; 
     } 
    } 
} 
28

añadir a cualquier Class:

public class Foo 
{ 
    public object this[string propertyName] 
    { 
     get { return this.GetType().GetProperty(propertyName).GetValue(this, null); } 
     set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); } 
    } 

    public string Bar { get; set; } 
} 

A continuación, se puede utilizar como:

Foo f = new Foo(); 
// Set 
f["Bar"] = "asdf"; 
// Get 
string s = (string)f["Bar"]; 

Sour ce: Get property value from string using reflection in C#

+0

¿Qué hay del rendimiento cuando se compara con una solución de diccionario? –

+0

¡Muy lento! Pero la pregunta es "C# setting/getting the class properties by string name", about "class", no about "Dictionary" –

+1

@ cristian-e ¿cuál es la solución del diccionario? – dsi

Cuestiones relacionadas