C#4.0 System.Dynamic

System.Dynamic 命名空间提供支持动态语言运行时的类和接口。

代码下载地址:GitHub

本篇主要讲两个类:①ExpandoObject   ②DynamicObject  (重点)

①ExpandoObject   

参考https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/

下面分别是XML和ExpandoObject设置与取值

 

对于集合:

 

XML和ExpandoObject各有各的好,把他们看做朋友关系,而ExpandoObject很容易转化为Dictionary类型。我们利用DynamicObject这个类来升级,转化为真正的动态类

 

 ②DynamicObject    本篇的主人翁

参考:https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/

 

DynamicXML类:

 public class DynamicXml : DynamicObject  //不能直接实例化,我们只能继承它了
    {
        //可以根据具体需求来进行逻辑实现
        public XElement xNode;  
        public DynamicXml(XElement node)
        {
            this.xNode = node;
        }

        public DynamicXml()
        {

        }

        public DynamicXml(string name)
        {
            xNode = new XElement(name);
        }

        /// <summary>
        /// 设置值  实例化该类的时候就会进入改方法
        /// </summary>
        /// <param name="binder">动态设置成员操作</param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            XElement setNode = xNode.Element(binder.Name);  
            if (setNode != null)//如果存在改节点
            {
                setNode.SetValue(value);  //就直接赋值
            }
            else
            {
                if (value.GetType() == typeof(DynamicXml)) //如果值为动态就调用自己,知道值为确定类型
                {
                    xNode.Add(new XElement(binder.Name));
                }
                else
                {
                    xNode.Add(new XElement(binder.Name, value)); //添加节点
                }
            }
            return true;
        }


        //取值 实例化该类的时候就会进入改方法
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            XElement getNode = xNode.Element(binder.Name);
            if (getNode != null)
            {
                result = new DynamicXml(getNode);
            }
            else
            {
                result = new DynamicXml(binder.Name);    //result = null;  这是案例的返回值,如果这样我们做测试的时候Address就会为空,这里需要改一下
            }
            return true;
        }



        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            if (binder.Type == typeof(string))
            {
                result = xNode.Value;
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }



        public override bool TryInvokeMember(
InvokeMemberBinder binder, object[] args, out object result)
        {
            Type xmlType = typeof(XElement);
            try
            {
                result = xmlType.InvokeMember(
                          binder.Name,
                          BindingFlags.InvokeMethod |
                          BindingFlags.Public |
                          BindingFlags.Instance,
                          null, this.xNode, args);
                return true;
            }
            catch
            {
                result = null;
                return false;
            }
        }
    }
View Code

 

DynamicObjext和XML的转换

 

 

 

posted @ 2018-03-05 17:49  Sealee  阅读(1197)  评论(0编辑  收藏  举报