代码之家  ›  专栏  ›  技术社区  ›  M4N

ExpandoObject、DynamicObject和dynamic之间的区别

  •  154
  • M4N  · 技术社区  · 14 年前

    它们之间有什么区别 System.Dynamic.ExpandoObject , System.Dynamic.DynamicObject dynamic ?

    您在哪些情况下使用这些类型?

    4 回复  |  直到 13 年前
        1
  •  159
  •   RJFalconer    8 年前

    这个 dynamic 关键字用于声明应该后期绑定的变量。
    如果您想使用后期绑定,对于任何真实或想象的类型,您可以使用 关键字,编译器执行其余的操作。

    当你使用 关键字与普通实例交互 DLR 对实例的常规方法执行后期绑定调用。

    IDynamicMetaObjectProvider interface 允许类控制其后期绑定行为。
    当你使用 动态 关键字与 实现时,DLR调用 方法和对象本身决定要做什么。

    这个 ExpandoObject DynamicObject IDynamicMetaObjectProvider

    动态 艾丽。
    是一个更高级的实现,可以继承它来轻松地提供定制的行为。

        2
  •  77
  •   Ayo I    7 年前

    ExpandoObject DynamicObject .

    很快, dynamic 是一个关键字。它本身不是一种类型。它是一个关键字,告诉编译器在设计时忽略静态类型检查,而在运行时使用后期绑定。所以我们不会花太多时间 动态 在这个答案的其余部分。

    展开对象 动态对象 确实是类型。从表面上看,它们看起来非常相似。两个类都实现了 IDynamicMetaObjectProvider . 然而,再深入一点,你会发现它们一点都不相似。

    DynamicObject是 IDynamicMetaObjectProvider

    1. 您必须扩展DynamicObject,它才能对您作为开发人员有任何用处。
    2. 当您扩展DynamicObject时,您现在可以提供有关如何在运行时将动态调度解析为内部存储在底层数据表示中的数据的自定义行为。

    简而言之,当您想要创建自己的类型,这些类型可以与DLR一起使用,并且可以处理您想要的任何自定义行为时,请使用DynamicObject。

    展开对象 .

    您可以按如下方式创建一个类型:(注意,下面的代码仅用于说明,可能无法运行。要了解如何正确使用DynamicObject,其他地方有许多文章和教程。)

    public class MyNoCookiesInTheJarDynamicObject : DynamicObject
    {
        Dictionary<string, object> properties = new Dictionary<string, object>();
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            if (properties.ContainsKey(binder.Name))
            {
                result = properties[binder.Name];
                return true;
            }
            else
            {
                result = "I'm sorry, there are no cookies in this jar!"; //<-- THIS IS OUR 
                CUSTOM "NO COOKIES IN THE JAR" RESPONSE FROM OUR DYNAMIC TYPE WHEN AN UNKNOWN FIELD IS ACCESSED
                return false;
            }
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            properties[binder.Name] = value;
            return true;
        }
    
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            dynamic method = properties[binder.Name];
            result = method(args[0].ToString(), args[1].ToString());
            return true;
        }
    }
    

    现在,我们可以使用这个我们刚刚创建的虚拟类作为一个动态类型,如果这个字段不存在,它有一个非常自定义的行为。

    dynamic d = new MyNoCookiesInTheJarDynamicObject();
    var s = d.FieldThatDoesntExist;
    
    //in our contrived example, the below should evaluate to true
    Assert.IsTrue(s == "I'm sorry, there are no cookies in this jar!")
    

    是对 IDynamicMetaObjectProvider 展开对象

    dynamic d = new ExpandoObject();
    
    /*
    The ExpandoObject designers chose that this operation should result in an 
    Exception. They did not have to make that choice, null could 
    have been returned, for example; or the designers could've returned a "sorry no cookies in the jar" response like in our custom class. However, if you choose to use 
    ExpandoObject, you have chosen to go with their particular implementation 
    of DynamicObject behavior.
    */
    
    try {
    var s = d.FieldThatDoesntExist;
    }
    catch(RuntimeBinderException) { ... }
    

    总之, ,但可能不取决于您的特殊需要。

    鉴于, DyanmicObject 是一个helper基类型,它使得用独特的动态行为实现自己的类型变得简单而容易。

    A useful tutorial on which much of the example source above is based.

        3
  •  36
  •   Brian Rasmussen    9 年前

    dynamic dynamic x x 具有类型 动态

    DynamicObject 是一种易于实现的类型 IDynamicMetaObjectProvider 从而重写类型的特定绑定行为。

    ExpandoObject 是一种类似于属性包的类型。也就是说,您可以在运行时向这种类型的动态实例添加属性、方法等。

        4
  •  0
  •   Diego Osornio flaudre    5 年前

    DynamicObject 因为它基本上实现了由提供的功能 ExpandoObject

    动态对象 ,可以保留/更改实际类型( XElement

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

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

    public class DynamicXMLNode : DynamicObject    
    {    
        XElement node;
    
        public DynamicXMLNode(XElement node)    
        {    
            this.node = node;    
        }
    
        public DynamicXMLNode()    
        {    
        }
    
        public DynamicXMLNode(String name)    
        {    
            node = new XElement(name);    
        }
    
        public override bool TrySetMember(SetMemberBinder binder, object value)    
        {    
            XElement setNode = node.Element(binder.Name);
    
            if (setNode != null)    
                setNode.SetValue(value);    
            else    
            {    
                if (value.GetType() == typeof(DynamicXMLNode))    
                    node.Add(new XElement(binder.Name));    
                else    
                    node.Add(new XElement(binder.Name, value));    
            }
    
            return true;    
        }
    
        public override bool TryGetMember(GetMemberBinder binder, out object result)    
        {    
            XElement getNode = node.Element(binder.Name);
    
            if (getNode != null)    
            {    
                result = new DynamicXMLNode(getNode);    
                return true;    
            }    
            else    
            {    
                result = null;    
                return false;    
            }    
        }    
    }