可以将动态对象转换为 ExpandoObject (c#) [英] can one convert a dynamic object to an ExpandoObject (c#)

查看:58
本文介绍了可以将动态对象转换为 ExpandoObject (c#)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am getting an dynamic object of type "Sealed Class" from a driver api (in dll). I want to decorate this object with a few additional properties.

我想做一些事情:

public void expandIT(dynamic sealedObject) {

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

<小时>

更新

我喜欢 JCL 的解决方案.但是对于我想做的事情,创建一个 ExpandoObject 然后将 Dynamic 密封类对象作为子属性嵌入,然后将我的属性添加到父 ExpandoObject 中会更容易.感谢 JCL,我对如何做到这一点感到茫然.我

I like JCL's solution. But for what I wanted to do, it was easier to create a ExpandoObject and then embed the Dynamic sealed class object as a child property, and then add my properties to the parent ExpandoObject. Thanks JCL, I was in brain-freeze as to how to do this. I

推荐答案

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

Nope. A dynamic object doesn't enforce the type at compile time, but it doesn't magically make your object expandable (unless it's an ExpandoObject).

但是,您可以使用 DynamicObject 来制作某种包装器或代理……例如:

You can however, make some kind of wrapper or proxy using DynamicObject... something like:

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;          
    }      
}

然后你可以像这样使用它:

And then you can use it like:

dynamic myExpandedObject = new ExpandedObjectFromApi(sealedObject);

如果找到,这应该返回原始对象属性,或者如果原始对象中没有该名称的属性,它会将其添加为自定义"属性.

This should return the original object properties if found, or if no property of that name is in the original object, it'll add it as a "custom" property.

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

I've made the code in the Stack Overflow editor and probably made a lot of mistakes, it's not suitable for copy/paste, and it needs tons of error checking (also needs to implement fields and methods, if the received object has them). Just wrote it so you get the basic idea.

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

You also may want to add a special property (something called WrappedObject, for example) and capture it in TryGetMember, so you can get the original object back.

这篇关于可以将动态对象转换为 ExpandoObject (c#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆