Convertir une classe en dynamic et append des propriétés

J’ai une classe MyClass . Je voudrais convertir ceci en un object dynamic afin que je puisse append une propriété.

C’est ce que j’avais espéré:

 dynamic dto = Factory.Create(id); dto.newProperty = "123"; 

Je reçois l’erreur:

 WEB.Models.MyClass does not contain a definition for 'newProperty' 

N’est-ce pas possible?

Ce qui suit a fonctionné pour moi dans le passé:
Il vous permet de convertir n’importe quel object en object Expando.

 public static dynamic ToDynamic(this T obj) { IDictionary expando = new ExpandoObject(); foreach (var propertyInfo in typeof(T).GetProperties()) { var currentValue = propertyInfo.GetValue(obj); expando.Add(propertyInfo.Name, currentValue); } return expando as ExpandoObject; } 

Basé sur: http://geekswithblogs.net/Nettuce/archive/2012/06/02/convert-dynamic-to-type-and-convert-type-to-dynamic.aspx

Vous ne pouvez pas append de propriétés aux types au moment de l’exécution. Cependant, il existe une exception qui est: ExpandoObject . Donc, si vous devez append des propriétés à l’exécution, vous devez utiliser ExpandoObject , les autres types ne le prennent pas en charge.

Vous ne pouvez pas append de membres aux instances de classe à la volée.

Mais vous pouvez utiliser ExpandoObject . Utilisez factory pour en créer un nouveau et initialisez-le avec les propriétés que vous avez dans MyClass :

 public static ExpandoObject Create(int id) { dynamic obj = new ExpandoObject(); obj.Id = id; obj.CreatedAt = DateTime.Now; // etc return obj; } 

Ensuite, vous pouvez append de nouveaux membres:

 dynamic dto = Factory.Create(id); dto.newProperty = "123"; 

Comme mon object a un nom spécifique à JSON, je l’ai proposé comme alternative:

 public static dynamic ToDynamic(this object obj) { var json = JsonConvert.SerializeObject(obj); return JsonConvert.DeserializeObject(json, typeof(ExpandoObject)); } 

Pour moi, les résultats ont très bien fonctionné:

Modèle:

 public partial class Settings { [JsonProperty("id")] public int Id { get; set; } [JsonProperty("runTime")] public TimeSpan RunTime { get; set; } [JsonProperty("retryInterval")] public TimeSpan RetryInterval { get; set; } [JsonProperty("retryCutoffTime")] public TimeSpan RetryCutoffTime { get; set; } [JsonProperty("cjisUrl")] public ssortingng CjisUrl { get; set; } [JsonProperty("cjisUserName")] public ssortingng CjisUserName { get; set; } [JsonIgnore] public ssortingng CjisPassword { get; set; } [JsonProperty("importDirectory")] public ssortingng ImportDirectory { get; set; } [JsonProperty("exportDirectory")] public ssortingng ExportDirectory { get; set; } [JsonProperty("exportFilename")] public ssortingng ExportFilename { get; set; } [JsonProperty("jMShareDirectory")] public ssortingng JMShareDirectory { get; set; } [JsonIgnore] public ssortingng Database { get; set; } } 

Je l’ai utilisé de cette manière:

 private static dynamic DynamicSettings(Settings settings) { var settingsDyn = settings.ToDynamic(); if (settingsDyn == null) return settings; settingsDyn.guid = Guid.NewGuid(); return settingsDyn; } 

Et reçu ceci comme résultat:

 { "id": 1, "runTime": "07:00:00", "retryInterval": "00:05:00", "retryCutoffTime": "09:00:00", "cjisUrl": "xxxxxx", "cjisUserName": "xxxxx", "importDirectory": "import", "exportDirectory": "output", "exportFilename": "xxxx.xml", "jMShareDirectory": "xxxxxxxx", "guid": "210d936e-4b93-43dc-9866-4bbad4abd7e7" } 

Je ne connais pas la vitesse, je veux dire que c’est la sérialisation et la désérialisation, mais pour mon utilisation, ça a été génial. Beaucoup de flexibilité comme les propriétés de masquage avec JsonIgnore.

Remarque: xxxxx ci-dessus correspond à la rédaction. 🙂