首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ExpandoObject、DynamicObject和dynamic之间的区别

ExpandoObject、DynamicObject和dynamic之间的区别
EN

Stack Overflow用户
提问于 2010-08-25 19:51:22
回答 4查看 52.3K关注 0票数 181

System.Dynamic.ExpandoObjectSystem.Dynamic.DynamicObjectdynamic之间的区别是什么

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

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-08-25 19:57:38

dynamic关键字用于声明应后期绑定的变量。

如果您想要对任何真实的或想象的类型使用后期绑定,您可以使用dynamic关键字,编译器将完成剩下的工作。

当您使用dynamic关键字与普通实例交互时,DLR将对该实例的普通方法执行后期绑定调用。

IDynamicMetaObjectProvider interface允许类控制其后期绑定行为。

当您使用dynamic关键字与IDynamicMetaObjectProvider实现交互时,DLR调用IDynamicMetaObjectProvider方法,对象本身决定要做什么。

ExpandoObjectDynamicObject类是IDynamicMetaObjectProvider的实现。

ExpandoObject是一个简单的类,它允许您将成员添加到实例中并在dynamic中使用它们。

DynamicObject是一个更高级的实现,可以继承它来轻松地提供自定义行为。

票数 162
EN

Stack Overflow用户

发布于 2017-06-21 10:01:45

我将尝试为这个问题提供一个更清晰的答案,以清楚地解释dynamic、ExpandoObjectDynamicObject之间的区别。

很快,dynamic是一个关键字。它本身不是一个类型。它是一个关键字,告诉编译器在设计时忽略静态类型检查,而在运行时使用后期绑定。因此,在接下来的回答中,我们将不会在dynamic上花费太多时间。

ExpandoObjectDynamicObject确实是类型。从表面上看,它们看起来非常相似。两个类都实现了IDynamicMetaObjectProvider。然而,深入挖掘,你会发现它们一点也不相似。

DynamicObject是的部分实现,它纯粹是开发人员实现自己的自定义类型的起点,支持使用自定义的底层存储和检索行为进行动态调度,从而实现动态调度。

  1. DynamicObject不能被构造directly.
  2. You必须扩展DynamicObject才能使它作为您扩展的DynamicObject对您有任何用处您现在可以提供自定义行为,关于您希望动态调度如何解析内部存储在底层数据表示中的数据在run-time.
  3. ExpandoObject中存储底层数据在字典中存储底层数据等等。(例如,如何获取和设置调度数据完全取决于您)。

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

示例:假设您希望有一个动态类型,每当尝试对不存在的成员(即未在运行时添加的成员)执行get操作时,该类型将返回自定义默认值。默认情况下会显示“对不起,这个jar中没有cookie!”。如果你想要一个像这样的动态对象,你需要控制当一个字段找不到时发生的事情。ExpandoObject不会让你这么做的。因此,您需要创建自己的具有独特动态成员解析(分派)行为的类型,并使用它来代替现成的ExpandoObject

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

代码语言:javascript
复制
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;
    }
}

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

代码语言:javascript
复制
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!")

ExpandoObjectIDynamicMetaObjectProvider的完整实现,.NET框架团队已经为您做出了所有这些决定。如果您不需要任何自定义行为,并且您觉得ExpandoObject对您来说足够好(90%的情况下,ExpandoObject就足够好),这将非常有用。例如,请参见以下内容,对于ExpandoObject,设计者选择在动态成员不存在的情况下抛出异常。

代码语言:javascript
复制
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) { ... }

因此,总而言之,ExpandoObject 只是一种预先选择的方式,用于使用某些动态分派行为来扩展DynamicObject,这些动态分派行为可能对您的有效,但可能不取决于您的特定需求。

然而,DyanmicObject 是一个辅助BaseType,它使实现您自己的具有独特动态行为的类型变得简单容易。

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

票数 84
EN

Stack Overflow用户

发布于 2010-08-25 19:56:16

根据C#语言规范,dynamic是一种类型声明。即dynamic x表示变量x的类型为dynamic

DynamicObject是一种可以轻松实现IDynamicMetaObjectProvider的类型,因此可以覆盖该类型的特定绑定行为。

ExpandoObject是一种类似于属性包的类型。即,您可以在运行时将属性、方法等添加到此类型的动态实例中。

票数 37
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3565481

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档