De acuerdo con esto: Adding properties and methods to an ExpandoObject, dynamically!,
... puede utilizar un objeto expando como el titular de su valor, y lo echó a un IDictionary < cadena, objeto > cuando se desea agregar propiedades con nombres dinámicos.
Ejemplo
dynamic myobject = new ExpandoObject();
IDictionary<string, object> myUnderlyingObject = myobject;
myUnderlyingObject.Add("IsDynamic", true); // Adding dynamically named property
Console.WriteLine(myobject.IsDynamic); // Accessing the property the usual way
Th se prueba y se imprimirá "verdadero" en la pantalla de la consola.
Por supuesto, en su caso, donde su objeto subyacente tiene que heredar de otra clase, este ejemplo se da solo para darle una idea de una posible implementación personalizada.
¿Quizás incluir un objeto expandido en su implementación de clase y redirigir llamadas a tryget y tryset a la instancia del objeto expando en su clase?
ACTUALIZACIÓN
SI su clase base se deriva de DynamicObject (lo que significa que puede anular todas TrySet/Obtener/invocar métodos) a continuación, también se puede usar un diccionario interno. En las anulaciones try get/set, realizará cualquier disparo de evento que desee y delegará la configuración al diccionario interno.
Para agregar una nueva propiedad (o eliminar una existente) puede anular TryInvoke. Cuando el nombre de mothod es, por ejemplo, "AddProperty" y hay un argumento de tipo string, entonces debería agregar un nuevo elemento en su diccionario con el nombre del argumento. Del mismo modo, definiría dinámicamente un "RemoveProperty", etc. Ni siquiera necesita un objeto expando.
class MyBaseClass: DynamicObject
{
// usefull functionality
}
class MyClass: MyBaseClass
{
Dictionary<string, object> dynamicProperties = new Dictionary<string, object>();
override bool TryGetMember(...)
{
// read the value of the requested property from the dictionary
// fire any events and return
}
override bool TrySetMember(...)
{
// set the value of the requested property to the dictionary
// if the property does not exist,
// add it to the dictionary (compile time dynamic property naming)
// fire any events
}
override bool TryInvoke(...)
{
// check what method is requested to be invoked
// is it "AddProperty"??
// if yes, check if the first argument is a string
// if yes, add a new property to the dictionary
// with the name given in the first argument (runtime dynamic property naming)
// if there is also a second argument of type object,
// set the new property's value to that object.
// if the method to be invoked is "RemoveProperty"
// and the first argument is a string,
// remove from the Dictionary the property
// with the name given in the first argument.
// fire any events
}
}
// USAGE
static class Program
{
public static void Main()
{
dynamic myObject = new MyClass();
myObject.FirstName = "John"; // compile time naming - TrySetMember
Console.WriteLine(myObject.FirstName); // TryGetMember
myObject.AddProperty("Salary"); // runtime naming (try invoke "AddProperty" with argument "Salary")
myObject.Salary = 35000m;
Console.WriteLine(myObject.Salary); // TryGetMember
myObject.AddProperty("DateOfBirth", new DateTime(1980,23,11)); // runtime naming (try invoke "AddProperty" with fisrt argument "DateOfBirth" and second argument the desired value)
Console.WriteLine(myObject.DateOfBirth); // TryGetMember
myObject.RemoveProperty("FirstName"); // runtime naming (try invoke "RemoveProperty" with argument "FirstName")
Console.WriteLine(myObject.FirstName); // Should print out empty string (or throw, depending on the desired bahavior) because the "FirstName" property has been removed from the internal dictionary.
}
}
Por supuesto, como ya he dicho, que funcionaría sólo si su clase base se deriva de DynamicObject.
Aún no entiende WHY dynamic y ExpandoObject entraron en .NET. La razón era exactamente lo contrario de lo que quieres. ExpandoObject todavía usa Dictionary, y es IS Dictionary. El compilador solo traduce todas las llamadas de "propiedad" a Dictionary [NameOfProperty]. Esto hace que el código sea mucho más agradable. Pero eso es todo, es solo código-azúcar. Lo que quiere se puede lograr con el diccionario incluso sin tipear dinámicamente. –
Euphoric
¿Qué pasa con los eventos que deben plantearse como elementos del diccionario? – sbenderli
posible duplicación de [Agregar miembros dinámicamente a un objeto dinámico] (http: // stackoverflow.com/questions/2079870/dynamically-adding-members-to-a-dynamic-object) – nawfal