2017-03-16 20 views
1

私はクラスMyClassを持っています。これを動的オブジェクトに変換して、プロパティを追加することができます。クラスを動的に変換してプロパティを追加します

これは私が望んでいたものです:

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

私はエラーを取得する:

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

はできないということですか?

+7

動的であっても、外出先でプロパティを追加することはできません。それは、あなたが動的である(私が知る限り)ものを使用するようになるため、実行時にその型が分かるようになるかどうかわからないことを意味します。 – EpicKip

+0

プロパティを追加する場合は、[ExpandoObject](https://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v = vs.110).aspx)を使用する必要があります。ここには、[リンク](http://stackoverflow.com/questions/3540161/c-sharp-4-0-dynamic-vs-expando-where-do-they-fit)が役立つかもしれない情報があります。 – MaKCbIMKo

答えて

2

以下は私の過去の仕事です:
これは、任意のオブジェクトをExpandoオブジェクトに変換することを可能にします。あなたがその場でクラスインスタンスにメンバーを追加することはできませんhttp://geekswithblogs.net/Nettuce/archive/2012/06/02/convert-dynamic-to-type-and-convert-type-to-dynamic.aspx

+0

これは私が欲しいものに近いですが、エラーが発生します。タイプ 'System.Guid'の式は、戻り値の型 'Systemに使用できません。String ' – Sean

+0

式ツリーに 'expando.Add(propertyInfo.Name、propertyInfo.GetValue(obj));でどのような利点がありますか?なぜプロパティ名を小文字に変換するのですか?なぜ、 'ExpandoObject'を' ExpandoObject'にキャストするのですか? – chris

+0

@Sean更新された返信をご覧ください – StfBln

1

実行時に型にプロパティを追加することはできません。ただし、例外は:ExpandoObjectです。したがって、実行時にプロパティを追加する必要がある場合はExpandoObjectを使用し、他のタイプではこれをサポートしません。

1

:に基づいて

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; 
} 

でも、ExpandoObjectを使用できます。新しいものを作成し、MyClassに持っている性質とそれを初期化するために工場を使用します。

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

その後、新しいメンバーを追加することができます:私のオブジェクトをJSON特定のネーミングを持っていたよう

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

を、私が思い付きましたこれは、代替として:

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

は、私にとってこの結果は素晴らしい仕事:

モデル:

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; } 
} 

が、私はこの方法でそれを使用:

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

そして、結果としてこれを受け取っ:

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

私はスピードを知らない、私はそれがある意味しますシリアライズとデシリアライズがありましたが、私の使用には素晴らしいことでした。 JsonIgnoreでプロパティを隠すような柔軟性がたくさんあります。

注:上記のxxxxxは改ざんされています。 :)

関連する問題