Establecer propiedad del objeto usando la reflexión
¿Hay alguna manera en C# en la que pueda usar la reflexión para establecer una propiedad de objeto?
Ex:
MyObject obj = new MyObject();
obj.Name = "Value";
Quiero ambientar obj.Name
con reflexión. Algo como:
Reflection.SetProperty(obj, "Name") = "Value";
¿Hay alguna forma de hacer esto?
Sí, puedes usar Type.InvokeMember()
:
using System.Reflection;
MyObject obj = new MyObject();
obj.GetType().InvokeMember("Name",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
Type.DefaultBinder, obj, "Value");
Esto generará una excepción si obj
no tiene una propiedad llamada Name
o no se puede configurar.
Otro enfoque es obtener los metadatos de la propiedad y luego configurarlos. Esto le permitirá verificar la existencia de la propiedad y verificar que se puede configurar:
using System.Reflection;
MyObject obj = new MyObject();
PropertyInfo prop = obj.GetType().GetProperty("Name", BindingFlags.Public | BindingFlags.Instance);
if(null != prop && prop.CanWrite)
{
prop.SetValue(obj, "Value", null);
}
También puedes hacer:
Type type = target.GetType();
PropertyInfo prop = type.GetProperty("propertyName");
prop.SetValue (target, propertyValue, null);
donde objetivo es el objeto al que se le establecerá su propiedad.
Reflexión, básicamente, es decir.
myObject.GetType().GetProperty(property).SetValue(myObject, "Bob", null);
o hay bibliotecas que ayudan tanto en términos de comodidad como de rendimiento; por ejemplo con FastMember :
var wrapped = ObjectAccessor.Create(obj);
wrapped[property] = "Bob";
(que también tiene la ventaja de no necesitar saber de antemano si se trata de un campo o de una propiedad)
O podrías envolver la única línea de Marc dentro de tu propia clase de extensión:
public static class PropertyExtension{
public static void SetPropertyValue(this object obj, string propName, object value)
{
obj.GetType().GetProperty(propName).SetValue(obj, value, null);
}
}
y llámalo así:
myObject.SetPropertyValue("myProperty", "myValue");
Por si acaso, agreguemos un método para obtener el valor de una propiedad:
public static object GetPropertyValue(this object obj, string propName)
{
return obj.GetType().GetProperty(propName).GetValue (obj, null);
}