2017-03-16 4 views
1

Ich habe eine Klasse MyClass. Ich möchte dies in ein dynamisches Objekt konvertieren, damit ich eine Eigenschaft hinzufügen kann.Klasse in dynamische konvertieren und Eigenschaften hinzufügen

Das ist das, was ich hatte gehofft, für:

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

bekomme ich den Fehler:

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

Ist das nicht möglich?

+7

dynamisch bedeutet nicht, dass Sie Eigenschaften auf dem Sprung hinzufügen können. Es bedeutet, dass Sie nicht wissen, was es sein wird, also verwenden Sie dynamisch (so weit ich weiß), und der Typ wird zur Laufzeit herausgefunden. – EpicKip

+0

Sie müssen [ExpandoObject] (https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject (v = vs.110) .aspx) verwenden, wenn Sie Eigenschaften hinzufügen möchten. Hier ist ein [link] (http://stackoverflow.com/questions/3540161/c-sharp-4-0-dynamic-vs-expando-where-do-they-fit) mit einigen Informationen, die helfen könnten. – MaKCbIMKo

Antwort

2

Das folgende hat für mich in der Vergangenheit funktioniert:
Es ermöglicht Ihnen, jedes Objekt in ein Expando-Objekt zu konvertieren.

public static dynamic ToDynamic<T>(this T obj) 
{ 
    IDictionary<string, object> expando = new ExpandoObject(); 

    foreach (var propertyInfo in typeof(T).GetProperties()) 
    { 
     var currentValue = propertyInfo.GetValue(obj); 
     expando.Add(propertyInfo.Name, currentValue); 
    } 
    return expando as ExpandoObject; 
} 

Basierend auf: http://geekswithblogs.net/Nettuce/archive/2012/06/02/convert-dynamic-to-type-and-convert-type-to-dynamic.aspx

+0

Das ist nahe, was ich will, aber ich bekomme einen Fehler: Ausdruck des Typs 'System.Guid' kann nicht für den Rückgabetyp 'System verwendet werden.String ' – Sean

+0

Welchen Vorteil hat der Ausdrucksbaum gegenüber 'expando.Add (propertyInfo.Name, propertyInfo.GetValue (obj));'? Und warum konvertiert es Eigenschaftsnamen in Kleinbuchstaben? Und warum wirft es bei der Rückgabe ein 'ExpandoObject' nach' ExpandoObject'? – chris

+0

@Sean Siehe die aktualisierte answeer – StfBln

1

Sie können den Typen zur Laufzeit keine Eigenschaften hinzufügen. Es gibt jedoch eine Ausnahme, die lautet: ExpandoObject. Wenn Sie also Eigenschaften zur Laufzeit hinzufügen müssen, sollten Sie ExpandoObject verwenden, andere Typen unterstützen dies nicht.

1

Sie nicht Mitglieder Klasseninstanzen on the fly hinzufügen können.

Aber Sie können ExpandoObject verwenden. Verwenden Sie Fabrik neue zu erstellen und initialisieren es mit Eigenschaften, die Sie in MyClass haben:

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

Dann können Sie neue Mitglieder hinzufügen:

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

Als mein Objekt JSON spezifische Namensgebung hat, kam ich mit dies als eine Alternative:

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

Für mich sind die Ergebnisse hat super funktioniert:

Modell:

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 string CjisUrl { get; set; } 

    [JsonProperty("cjisUserName")] 
    public string CjisUserName { get; set; } 

    [JsonIgnore] 
    public string CjisPassword { get; set; } 

    [JsonProperty("importDirectory")] 
    public string ImportDirectory { get; set; } 

    [JsonProperty("exportDirectory")] 
    public string ExportDirectory { get; set; } 

    [JsonProperty("exportFilename")] 
    public string ExportFilename { get; set; } 

    [JsonProperty("jMShareDirectory")] 
    public string JMShareDirectory { get; set; } 

    [JsonIgnore] 
    public string Database { get; set; } 
} 

ich es auf diese Weise verwendet:

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

und erhielt dies als Ergebnis:

{ 
    "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" 
} 

ich über die Geschwindigkeit nicht wissen, ich meine, es ist Serialisierung und Deserialisierung, aber für meinen Gebrauch war es großartig. Viel Flexibilität wie Verstecken mit JsonIgnore.

Hinweis: xxxxx oben ist Redaktion. :)

Verwandte Themen