2010-08-09 14 views
5

Estoy configurando una clase de ayuda simple para contener algunos datos de un archivo que estoy analizando. Los nombres de las propiedades coinciden con los nombres de los valores que espero encontrar en el archivo. Me gustaría agregar un método llamado AddPropertyValue a mi clase para poder asignar un valor a una propiedad sin llamarlo explícitamente por nombre.¿Es posible pasar un nombre de propiedad como una cadena y asignarle un valor?

El método se vería así:

//C# 
public void AddPropertyValue(string propertyName, string propertyValue) { 
    //code to assign the property value based on propertyName 
} 

--- 

'VB.NET' 
Public Sub AddPropertyValue(ByVal propertyName As String, _ 
          ByVal propertyValue As String) 
    'code to assign the property value based on propertyName ' 
End Sub 

La aplicación podría tener este aspecto:

C#/VB.NET

MyHelperClass.AddPropertyValue("LocationID","5") 

¿Es esto posible sin tener que probar para cada nombre de propiedad individual contra el propertyName suministrado?

+0

muy similar a este post anterior: http://stackoverflow.com/questions/110562/how-to-pass-a-generic-property-as-a- parameter-to-a-function – David

Respuesta

7

Puede hacer esto con la reflexión, llamando al Type.GetProperty y luego al PropertyInfo.SetValue. Deberá hacer un manejo de errores adecuado para verificar que la propiedad no esté realmente presente.

He aquí una muestra:

using System; 
using System.Reflection; 

public class Test 
{ 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public void AddPropertyValue(string name, string value) 
    { 
     PropertyInfo property = typeof(Test).GetProperty(name); 
     if (property == null) 
     { 
      throw new ArgumentException("No such property!"); 
     } 
     // More error checking here, around indexer parameters, property type, 
     // whether it's read-only etc 
     property.SetValue(this, value, null); 
    } 

    static void Main() 
    { 
     Test t = new Test(); 
     t.AddPropertyValue("Foo", "hello"); 
     t.AddPropertyValue("Bar", "world"); 

     Console.WriteLine("{0} {1}", t.Foo, t.Bar); 
    } 
} 

Si usted tiene que hacer esto muchas veces, puede convertirse en un gran dolor en términos de rendimiento. Hay trucos en torno a los delegados que pueden hacerlo mucho más rápido, pero vale la pena hacerlo funcionar primero.

4

El uso de la reflexión se obtiene el establecimiento en el nombre y configura su valor ... algo así como:

Type t = this.GetType(); 
var prop = t.GetProperty(propName); 
prop.SetValue(this, value, null); 
2

En cuanto a la organización del código, se puede hacer de una manera mixin-like (gastos de envío aparte de error) :

public interface MPropertySettable { } 
public static class PropertySettable { 
    public static void SetValue<T>(this MPropertySettable self, string name, T value) { 
    self.GetType().GetProperty(name).SetValue(self, value, null); 
    } 
} 
public class Foo : MPropertySettable { 
    public string Bar { get; set; } 
    public int Baz { get; set; } 
} 

class Program { 
    static void Main() { 
    var foo = new Foo(); 
    foo.SetValue("Bar", "And the answer is"); 
    foo.SetValue("Baz", 42); 
    Console.WriteLine("{0} {1}", foo.Bar, foo.Baz); 
    } 
} 

de esta manera, se puede volver a utilizar esa lógica en muchas clases diferentes, sin sacrificar su clase base única preciosa con él.

En VB.NET:

Public Interface MPropertySettable 
End Interface 
Public Module PropertySettable 
    <Extension()> _ 
    Public Sub SetValue(Of T)(ByVal self As MPropertySettable, ByVal name As String, ByVal value As T) 
    self.GetType().GetProperty(name).SetValue(self, value, Nothing) 
    End Sub 
End Module 
+1

Y para get: public string estático GetValue (este IPropertySettable self, nombre de cadena) { return self.GetType(). GetProperty (name) .GetValue (self, null) .ToString() ; } –

Cuestiones relacionadas