可以将动态对象转换为ExpandoObject(c#)

时间:2016-04-11 19:43:42

标签: c# c#-4.0 expandoobject

我从驱动程序api(在dll中)获得了一个类型为“密封类”的动态对象。我想用一些额外的属性来装饰这个对象。

我想做点什么:

public void expandIT(dynamic sealedObject) {

    ExpandoObject expand = new ExpandoObject(sealedObject);
    expand.time = DateTime.Now();
    etc....
}

更新

我喜欢JCL的解决方案。但是对于我想要做的事情,创建一个ExpandoObject然后将Dynamic sealed class对象作为子属性嵌入,然后将我的属性添加到父ExpandoObject更容易。谢谢JCL,我正在大脑冻结如何做到这一点。 我

2 个答案:

答案 0 :(得分:14)

不。 dynamic对象在编译时不会强制执行该类型,但它不会神奇地使您的对象可扩展(除非它是ExpandoObject)。

但是,您可以使用DynamicObject制作某种包装或代理......类似于:

public class ExpandedObjectFromApi : DynamicObject
{
    private Dictionary<string, object> _customProperties = new Dictionary<string, object>();
    private object _currentObject;

    public ExpandedObjectFromApi(dynamic sealedObject)
    {
      _currentObject = sealedObject;
    }

    private PropertyInfo GetPropertyInfo(string propertyName) 
    { 
       return _currentObject.GetType().GetProperty(propertyName);
    } 

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
      var prop = GetPropertyInfo(binder.Name);
      if(prop != null)
      {
         result = prop.GetValue(_currentObject);
         return true;
      }
      result = _customProperties[binder.Name];
      return true;          
    }      

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
      var prop = GetPropertyInfo(binder.Name);
      if(prop != null)
      {
         prop.SetValue(_currentObject, value);
         return true;
      }
      if(_customProperties.ContainsKey(binder.Name))
        _customProperties[binder.Name] = value;
      else
        _customProperties.Add(binder.Name, value);
      return true;          
    }      
}

然后您就可以使用它:

dynamic myExpandedObject = new ExpandedObjectFromApi(sealedObject);

这应该返回原始对象属性(如果找到),或者如果原始对象中没有该名称的属性,则将其添加为&#34; custom&#34;属性。

我已经在Stack Overflow编辑器中编写了代码并且可能犯了很多错误,它不适合复制/粘贴,并且需要大量的错误检查(还需要实现字段和方法,如果收到的对象有它们)。只是写了它,所以你得到了基本的想法。

您还可能想要添加一个特殊属性(例如,名为WrappedObject)并在TryGetMember中捕获它,这样您就可以恢复原始对象。

答案 1 :(得分:5)

 ExpandoObject eo=JsonConvert. Deserialize<ExpandoObject>(JsonConvert.Serialize(dynamicObject))

为我工作,将动态对象更改为ExpandoObject。