Aggiungi dynamicmente le proprietà C # in fase di runtime

So che ci sono alcune domande che affrontano questo problema, ma le risposte di solito seguono le linee di raccomandare un dizionario o una raccolta di parametri, che non funziona nella mia situazione.

Sto usando una libreria che funziona attraverso la riflessione per fare molte cose intelligenti con oggetti con proprietà. Funziona con classi definite e classi dinamiche. Devo fare un ulteriore passo avanti e fare qualcosa in questo senso:

public static object GetDynamicObject(Dictionary 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(); 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 libreria funziona bene con un tipo di variabile dinamico, con proprietà assegnate manualmente. Tuttavia non so quante o quali proprietà verranno aggiunte in anticipo.

Hai dato un’occhiata a ExpandoObject?

vedere: http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introducing-the-expandoobject.aspx

Da MSDN:

La class ExpandoObject consente di aggiungere ed eliminare membri delle sue istanze in fase di esecuzione e anche di impostare e ottenere i valori di questi membri. Questa class supporta l’associazione dynamic, che consente di utilizzare la syntax standard come sampleObject.sampleMember anziché la syntax più complessa come sampleObject.GetAttribute (“sampleMember”).

Permettendoti di fare cose interessanti come:

 dynamic dynObject = new ExpandoObject(); dynObject.SomeDynamicProperty = "Hello!"; dynObject.SomeDynamicAction = (msg) => { Console.WriteLine(msg); }; dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty); 

In base al tuo codice attuale potresti essere più interessato a:

 public static dynamic GetDynamicObject(Dictionary properties) { return new MyDynObject(properties); } public sealed class MyDynObject : DynamicObject { private readonly Dictionary _properties; public MyDynObject(Dictionary properties) { _properties = properties; } public override IEnumerable 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; } } } 

In questo modo hai solo bisogno di:

 var dyn = GetDynamicObject(new Dictionary() { {"prop1", 12}, }); Console.WriteLine(dyn.prop1); dyn.prop1 = 150; 

Derivando da DynamicObject ti permette di elaborare la tua strategia per gestire queste richieste dinamiche dei membri, fai attenzione che qui ci siano mostri: il compilatore non sarà in grado di verificare molte delle tue chiamate dinamiche e non otterrai intellisense, quindi basta tenere questo in mente.

Grazie a @Clint per l’ottima risposta:

Volevo solo evidenziare quanto fosse facile risolvere questo problema usando l’Expando Object:

  var dynamicObject = new ExpandoObject() as IDictionary; foreach (var property in properties) { dynamicObject.Add(property.Key,property.Value); }