System.Dynamic 命名空间提供支持动态语言运行时的类和接口。
代码下载地址:GitHub
本篇主要讲两个类:①ExpandoObject ②DynamicObject (重点)
①ExpandoObject
下面分别是XML和ExpandoObject设置与取值
对于集合:
XML和ExpandoObject各有各的好,把他们看做朋友关系,而ExpandoObject很容易转化为Dictionary类型。我们利用DynamicObject这个类来升级,转化为真正的动态类。
②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; } } }
DynamicObjext和XML的转换