• .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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。
  • 相关阅读:
    Python 0001:生成激活码
    Python pillow
    python file and stream
    猴子选大王问题(Monkey King)
    python 杨辉三角
    python random
    window.showModalDialog的简单实践
    Java Web 编程
    Java基础和JDK5.0新特性
    Base64加密工具-iBlogs
  • 原文地址:https://www.cnblogs.com/Henllyee/p/1775302.html
Copyright © 2020-2023  润新知