.Net 4.0 DynamicObject使用(下)

上篇文章中我们看过了DynamicObject的基本使用,这篇文章中我们通过Dynamic来实现一个操作xml的动态类型,让我们更为方便的操作xml。

其实在前面的使用ExpandoObject的文章中我们已经,通过ExpandoObject来实现了操作Xml,并体现了动态性,但是不好的是,里面没有Linq to Xml大量Api的支持,操作起来很不方便,同时我们需要编写大量的辅助方法才行。而DynamicObject可以让我们自己决定动态运行时的操作方式,我们可以很快想到通过借助XElement来实现。是的,我的想法就是这样的。

基本实现

来看看我们的Linq to Xml的语法:

            var employee = new XElement(

                "Employee",

                new XElement("Name",

                    new XElement("FirstName","Henry"),

                    new XElement("LastName","Cui")),

                new XElement("Birthday","1987-10-14")

                );

现在我们可以借助DynamicObject来实现一种更为直观更为简洁的语法的创建Xml的方式。

首先我们来顶一个DynamicXNode类型,继承于DynamicObject:

 public class DynamicXNode:DynamicObject

    {

        private XElement _XElement;



        #region Constructor Methods

        public DynamicXNode(string name)

        {

            _XElement = new XElement(name);

        }



        public DynamicXNode(XElement node)

        {

            _XElement = node;

        }

        #endregion

   }

我们来重写下TryGetMember 跟TrySetMember方法:

        public override bool TryGetMember(GetMemberBinder binder, out object result)

        {

            var node = _XElement.Element(binder.Name);

            if (node != null)

            {

                result = new DynamicXNode(node);

                return true;

            }

            else

            {

                result = null;

                return false;

            }

        }



        public override bool TrySetMember(SetMemberBinder binder, object value)

        {

            var node = _XElement.Element(binder.Name);

            if (node != null)

            {

                node.SetValue(value);

            }

            else

            {

                //是否是复合的类型

                if (value is DynamicXNode)

                {

                    _XElement.Add(new XElement(binder.Name));

                }

                else

                {

                    _XElement.Add(new XElement(binder.Name, value.ToString()));

                }

            }

            return true;

        }

我们来写测试的代码看:

        [TestMethod()]

        public void DynamicXNodesTest()

        {

            dynamic employee = new DynamicXNode("Employee");

            employee.Name = new DynamicXNode("Name");

            employee.Name.FirstName = "Henry";

            employee.Name.LastName = "Cui";

            employee.Birthday = "1987-10-14";

        }

哦,我们还需要借助XElement来把它输出来,在重写下TryConvert方法吧:

        public override bool TryConvert(ConvertBinder binder, out object result)

        {

            if (binder.Type.Equals(typeof(XElement)))

            {

                result = _XElement;

                return true;

            }

            return base.TryConvert(binder, out result);

        }

之后我们输出来可以看到:

image

添加额外的东西

好像已经差不多了,可是我们这里还没有Api的支持啊,我们可以将动态的方法的Invoke通过XElement去Invoke,重写

TryInvokeMember,通过反射机制到XElement上执行吧:

        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)

        {

            var ttype = typeof(XElement);

            try

            {

                result = ttype.InvokeMember(binder.Name,

                             BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance,

                             null,

                             _XElement,

                             args);

                return true;

            }

            catch

            {

                result = null;

                return false;

            }

        }

总结

在这篇文章中我们看到了如果使用DynamicObject进行应用了,这里面只是一个xml操作的一个想法,还有许多需要去完善的地方。在.Net4.0中的动态性确实给我们带来了很大的惊喜,已经方便之处。

参考文档

Dynamic in C# 4.0: Creating Wrappers with DynamicObject  http://blogs.msdn.com/b/csharpfaq/archive/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject.aspx
作者:Henllyee Cui
出处: http://henllyee.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。

你可能感兴趣的:(dynamic)