プロパティをExpandoObjectに動的に追加する


233

実行時にExpandoObjectにプロパティを動的に追加したいと思います。たとえば、文字列プロパティ呼び出しを追加するために、NewPropを呼び出します。

var x = new ExpandoObject();
x.AddProperty("NewProp", System.String);

これは簡単に可能ですか?


回答:


489
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;

または:

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("NewProp", string.Empty);

32
Expando IDictionary <string、object>を実装していることを知りませんでした。キャストはそれを辞書にコピーすると思っていました。しかし、あなたの投稿により、Dictionaryを変更すると、基になるExpandoObjectも変更されることがわかりました。
どうも

3
取得Error 53 Cannot convert type 'System.Dynamic.ExpandoObject' to 'System.Collections.Generic.IDictionary<string,string>' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion
TheVillageIdiot 2012年

24
それはIDictionary<string, object>、ではありませんIDictionary<string, string>
スティーブンクリアリー2012年

3
@ user123456:プロパティ名は常に文字列です。動的にすることはできません。「動的」とは、「実行時までわからない」という意味の場合、2番目の例を使用する必要があります。「動的」とは、プロパティが動的であることを意味し、それで問題ありません。動的な値を持つことは、どちらの例でもうまくいきます。
Stephen Cleary 2016

3
キャストするときは、変数の型としてIDictionary使用しないことに注意してくださいdynamic
user3791372 2017年


14

以下は、オブジェクトを変換し、指定されたオブジェクトのすべてのパブリックプロパティを持つExpandoを返すサンプルヘルパークラスです。


    public static class dynamicHelper
        {
            public static ExpandoObject convertToExpando(object obj)
            {
                //Get Properties Using Reflections
                BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
                PropertyInfo[] properties = obj.GetType().GetProperties(flags);

                //Add Them to a new Expando
                ExpandoObject expando = new ExpandoObject();
                foreach (PropertyInfo property in properties)
                {
                    AddProperty(expando, property.Name, property.GetValue(obj));
                }

                return expando;
            }

            public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
            {
                //Take use of the IDictionary implementation
                var expandoDict = expando as IDictionary;
                if (expandoDict.ContainsKey(propertyName))
                    expandoDict[propertyName] = propertyValue;
                else
                    expandoDict.Add(propertyName, propertyValue);
            }
        }

使用法:

//Create Dynamic Object
dynamic expandoObj= dynamicHelper.convertToExpando(myObject);

//Add Custom Properties
dynamicHelper.AddProperty(expandoObj, "dynamicKey", "Some Value");

11
「var expandoDict = expando as IDictionary;」この行を「var expandoDict = expando as IDictionary <String、object>;」に変更する必要があります。
Jom George

0

これは、クラス定義でプロパティが定義されているときのように、プリミティブ値を設定する必要なく、目的のタイプに新しいプロパティを追加すると思います

var x = new ExpandoObject();
x.NewProp = default(string)

5
やあ、モルテザ!コードのみの回答は問題を解決する可能性がありますが、それをどのように解決するかを説明すると、はるかに役立ちます。コミュニティはあなたの答えを完全に理解するために理論とコードの両方を必要とします。
RBT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.