2013-07-23 12 views
6

匿名クラスに追加のプロパティを追加する方法はありますか(または追加のプロパティで新しいインスタンスを作成する方法)ですか?匿名クラスに追加のプロパティを追加する

string cssClasses = "hide"; 
object viewData = new { @class = cssClasses }; 
if (suppliedId != null) 
{ 
    // add an extra id property to the viewData somehow... 
    // desired end result is { @id = suppliedId, @class = cssClasses } 
} 
// ... code will be passing the viewData as the additionalViewData parameter in asp.mvc's .EditorFor method 

答えて

1

おかげで私はそれをExpandoObjectを使用して、外出先を与え、それは次のように働いてしまった:最後の行は、それが通過することができるようにMVCで働いて、それを得るための鍵となった

dynamic viewData = new ExpandoObject(); 
[email protected] = cssClasses; 
if (controlId != null) 
    viewData.id = controlId; 
if (title != null) 
    viewData.title = title; 
// put the result into a route value dictionary so that MVC's EditorFor (etc) can interpret it 
var additionalViewData = new RouteValueDictionary(viewData); 

ことEditorForなどのadditionalViewDataパラメータとして使用します。

私が匿名クラスを渡して自分自身に追加する必要がある状況では、リフレクションを使用しています(IDictionaryを実装するExpandoObjectを利用しています)。

[TestMethod] 
public void ShouldBeAbleToConvertAnAnonymousObjectToAnExpandoObject() 
{ 
    var additionalViewData = new {id = "myControlId", css = "hide well"}; 
    dynamic result = new ExpandoObject(); 
    var dict = (IDictionary<string, object>)result; 
    foreach (PropertyInfo propertyInfo in additionalViewData.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public)) 
    { 
    dict[propertyInfo.Name] = propertyInfo.GetValue(additionalViewData, null); 
    } 
    Assert.AreEqual(result.id, "myControlId"); 
    Assert.AreEqual(result.css, "hide well"); 
} 
6

いいえ、できません。あなたはそれを再定義することができます:

dynamic viewData = new { @class = cssClasses }; 
if (suppliedId != null) 
{ 
    viewData = new { @class = [email protected], yourExtra = Property }; 
} 

私はdynamicに変更しました。これは、ちょうどdynamicにキャストせずにプロパティを編集できるようにすることです。

+3

これはどちらかというと、代わりに 'ExpandoObject'で' dynamic'を使用します:) –

+0

@Patrykíwiek私はかなりexpandoObject tbhが好きです、それはかなりクールです。 –

+0

なぜあなたはコードに 'object'を残さなかったのか分かりません。問題の両方の匿名型は 'object'です。 –

2

匿名タイプに追加のプロパティを追加することはできませんが、2つの匿名タイプを使用できます。

あなたがdynamicを好きではない(との理由ではないのがある)場合は、あなたができる:

object viewData; 
if (suppliedId == null) 
    viewData = new { @class = cssClasses, }; 
else 
    viewData = new { @id = suppliedId, @class = cssClasses, }; 

をあなたが使用して、各オブジェクトのインスタンスに別々に正確に入力の参照を保持したい場合は:

var viewDataSimple = new { @class = cssClasses, }; 
var viewDataExtra = new { @id = suppliedId, @class = cssClasses, }; 
object viewDataToUse; 
if (suppliedId == null) 
    viewDataToUse = viewDataSimple; 
else 
    viewDataToUse = viewDataExtra; 

代わりにPatrykからのコメントへ

+0

+1それはまさに私がやっていたことです。今私はいくつかの追加のプロパティを持っているので、順列の数が手に入れています。 –

+0

@JonathanMoffattそれで、あなたは本当に[ExpandoObject'クラス](http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx)を 'System 'に入れたいと思うかもしれません。動的な名前空間。新しいメンバーを追加することで、正確に動作します。私がそこに与えたリンクの例を見てください。編集:ああ、ちょうどあなたがすでに見つけたあなたの新しい答えから見た。 –

0

あなたはあなたがです。KeyValueペアで新しいプロパティを追加することができますリフレクションを、使用して要件を達成することができます:ここで私はそれが動作することを確認するために書いたユニットテストです。

string cssClasses = "hide"; 
     object viewData = new { @class = cssClasses }; 
     dynamic expandoData = new ExpandoObject(); 
     var processedData = expandoData as IDictionary<String, object>; 
     if (viewData != null) 
     { 
      PropertyInfo[] properties = viewData.GetType().GetProperties(); 
      foreach (var prop in properties) 
      { 
       if (prop == null) continue; 
       object valueObj = viewData .GetType().GetProperty(prop.Name).GetValue(viewData , null); 
       processedData[prop.Name.ToString()] = valueObj; 
      } 
     }   
     processedData["AdditionalPropertyName"] = AdditionalProperty; 
     var infoJson = JsonConvert.SerializeObject(processedData); 
+0

あなたが提供した解決策を説明する必要があります。それは唯一の違いです。正解ではありません – DomTomCat

関連する問題