我从驱动程序api(在dll中)获得了一个类型为“密封类”的动态对象。我想用一些额外的属性来装饰这个对象。
我想做点什么:
public void expandIT(dynamic sealedObject) {
ExpandoObject expand = new ExpandoObject(sealedObject);
expand.time = DateTime.Now();
etc....
}
更新
我喜欢JCL的解决方案。但是对于我想要做的事情,创建一个ExpandoObject然后将Dynamic sealed class对象作为子属性嵌入,然后将我的属性添加到父ExpandoObject更容易。谢谢JCL,我正在大脑冻结如何做到这一点。 我
答案 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。