c# - varias - groupbox propiedades
Agregue dinámicamente propiedades de C#en tiempo de ejecución (2)
Sé que hay algunas preguntas que abordan esto, pero las respuestas generalmente siguen la línea de recomendar un diccionario o una colección de parámetros, que no funciona en mi situación.
Estoy usando una biblioteca que funciona a través de la reflexión para hacer muchas cosas inteligentes con objetos con propiedades. Esto funciona con clases definidas, así como clases dinámicas. Necesito dar un paso más y hacer algo en esta línea:
public static object GetDynamicObject(Dictionary<string,object> properties) {
var myObject = new object();
foreach (var property in properties) {
//This next line obviously doesn''t work...
myObject.AddProperty(property.Key,property.Value);
}
return myObject;
}
public void Main() {
var properties = new Dictionary<string,object>();
properties.Add("Property1",aCustomClassInstance);
properties.Add("Property2","TestString2");
var myObject = GetDynamicObject(properties);
//Then use them like this (or rather the plug in uses them through reflection)
var customClass = myObject.Property1;
var myString = myObject.Property2;
}
La biblioteca funciona bien con un tipo de variable dinámica, con propiedades asignadas manualmente. Sin embargo, no sé cuántas o qué propiedades se agregarán de antemano.
¿Has echado un vistazo a ExpandoObject?
Desde MSDN:
La clase ExpandoObject le permite agregar y eliminar miembros de sus instancias en tiempo de ejecución y también establecer y obtener valores de estos miembros. Esta clase admite el enlace dinámico, que le permite utilizar la sintaxis estándar como sampleObject.sampleMember en lugar de una sintaxis más compleja como sampleObject.GetAttribute ("sampleMember").
Permitiéndole hacer cosas geniales como:
dynamic dynObject = new ExpandoObject();
dynObject.SomeDynamicProperty = "Hello!";
dynObject.SomeDynamicAction = (msg) =>
{
Console.WriteLine(msg);
};
dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);
En función de su código real, puede estar más interesado en:
public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
return new MyDynObject(properties);
}
public sealed class MyDynObject : DynamicObject
{
private readonly Dictionary<string, object> _properties;
public MyDynObject(Dictionary<string, object> properties)
{
_properties = properties;
}
public override IEnumerable<string> GetDynamicMemberNames()
{
return _properties.Keys;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (_properties.ContainsKey(binder.Name))
{
result = _properties[binder.Name];
return true;
}
else
{
result = null;
return false;
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (_properties.ContainsKey(binder.Name))
{
_properties[binder.Name] = value;
return true;
}
else
{
return false;
}
}
}
De esa manera solo necesitas:
var dyn = GetDynamicObject(new Dictionary<string, object>()
{
{"prop1", 12},
});
Console.WriteLine(dyn.prop1);
dyn.prop1 = 150;
Derivarte de DynamicObject te permite crear tu propia estrategia para manejar estas solicitudes dinámicas de miembros, ten cuidado de que haya monstruos aquí: el compilador no podrá verificar muchas de tus llamadas dinámicas y no obtendrás intellisense, así que solo sigue eso en mente.
Gracias @Clint por la excelente respuesta:
Solo quería resaltar lo fácil que fue resolver esto usando el Objeto Expando:
var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
foreach (var property in properties) {
dynamicObject.Add(property.Key,property.Value);
}