我想在运行时动态地向ExpandoObject添加属性。例如,要添加一个名为NewProp的字符串属性,我想写这样的东西

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

这容易实现吗?


当前回答

这是我找到的最好的解决办法。但是要小心。使用异常处理,因为它可能不适用于所有情况

public static dynamic ToDynamic(this object obj)
{
    return JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));
}

//另一个你可能想要使用的扩展方法

    public static T JsonClone<T>(this T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", nameof(source));
        }

        var serialized = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(serialized);
    }

其他回答

正如Filip - http://www.filipekberg.se/2011/10/02/adding-properties-and-methods-to-an-expandoobject-dynamicly/所解释的

您也可以在运行时添加方法。

var x = new ExpandoObject() as IDictionary<string, Object>;
x.Add("Shout", new Action(() => { Console.WriteLine("Hellooo!!!"); }));
x.Shout();
dynamic x = new ExpandoObject();
x.NewProp = string.Empty;

另外:

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

下面是一个转换Object并返回带有给定对象的所有公共属性的Expando的示例helper类。

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<String, object>;
            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");

这是我找到的最好的解决办法。但是要小心。使用异常处理,因为它可能不适用于所有情况

    public static dynamic ToDynamic(this object obj)
    {
        return JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));
    }

这是我找到的最好的解决办法。但是要小心。使用异常处理,因为它可能不适用于所有情况

public static dynamic ToDynamic(this object obj)
{
    return JsonConvert.DeserializeObject<dynamic>(JsonConvert.SerializeObject(obj));
}

//另一个你可能想要使用的扩展方法

    public static T JsonClone<T>(this T source)
    {
        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serializable.", nameof(source));
        }

        var serialized = JsonConvert.SerializeObject(source);
        return JsonConvert.DeserializeObject<T>(serialized);
    }