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

can one convert a dynamic object to an ExpandoObject (c#)

我正在从驱动程序 api(在 dll 中)获取类型 "Sealed Class" 的动态对象。我想用一些额外的属性来装饰这个对象。

我想做一些事情:

public void expandIT(dynamic sealedObject) {

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

更新

我喜欢 JCL 的解决方案。但是对于我想做的事情,创建一个 ExpandoObject 然后将动态密封 class 对象作为子对象 属性 嵌入,然后将我的属性添加到父 ExpandoObject 更容易。感谢 JCL,对于如何执行此操作,我的大脑处于冻结状态。 我

没有。 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);

这应该 return 如果找到原始对象属性,或者如果在原始对象中没有 属性 该名称,它会将其添加为 "custom" 属性.

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

您可能还想添加一个特殊的 属性(例如称为 WrappedObject 的东西)并将其捕获到 TryGetMember,这样您就可以取回原始对象。

string json = JsonConvert.Serialize(dynamicObject);

ExpandoObject eo = JsonConvert.Deserialize<ExpandoObject>(json);

帮助我将 dynamic 更改为 ExpandoObject