M4N*_*M4N 162 .net c# dynamic expandoobject dynamicobject
之间有什么区别System.Dynamic.ExpandoObject,System.Dynamic.DynamicObject和dynamic?
在哪些情况下你使用这些类型?
SLa*_*aks 142
该dynamic关键字用于声明应该是后期绑定的变量.
如果你想使用后期绑定,对于任何真实或想象的类型,你使用dynamic关键字,编译器完成剩下的工作.
当您使用dynamic关键字与普通实例进行交互时,DLR会对实例的常规方法执行后期绑定调用.
该IDynamicMetaObjectProvider接口允许类控制其后期绑定行为.
当您使用dynamic关键字与IDynamicMetaObjectProvider实现交互时,DLR会调用IDynamicMetaObjectProvider方法,而对象本身会决定要执行的操作.
在ExpandoObject和DynamicObject类的实现IDynamicMetaObjectProvider.
ExpandoObject是一个简单的类,它允许您将成员添加到实例并使用它们dynamic.
DynamicObject是一种更高级的实现,可以继承以轻松提供自定义行为.
Ayo*_*o I 56
我将尝试为这个问题提供一个更清晰的答案,清楚地解释动态ExpandoObject和DynamicObject.之间的差异.
很快,dynamic是一个关键字.它本身不是一种类型.它是一个关键字,告诉编译器在设计时忽略静态类型检查,而不是在运行时使用后期绑定.所以我们不会dynamic在这个答案的其余部分花太多时间.
ExpandoObject并且DynamicObject确实类型.在SURFACE上,它们看起来非常相似.两个类都实现IDynamicMetaObjectProvider.然而,深入挖掘,你会发现它们根本不相似.
DynamicObject是一个部分实现,IDynamicMetaObjectProvider纯粹意味着开发人员可以实现自己的自定义类型,支持动态调度和自定义底层存储和检索行为,以实现动态调度工作.
简而言之,当您想要创建可与DLR一起使用的OWN类型并使用您想要的任何CUSTOM行为时,请使用DynamicObject.
示例:假设您想要一个动态类型,只要在不存在的成员上尝试获取(即在运行时尚未添加),就会返回自定义默认值.那个默认会说,"对不起,这个罐子里没有饼干!".如果您想要一个行为类似的动态对象,则需要控制未找到字段时发生的情况.ExpandoObject不允许你这样做.因此,您需要使用独特的动态成员解析(dispatch)行为创建自己的类型,并使用它而不是现成的ExpandoObject.
您可以按如下方式创建一个类型:(注意,下面的代码仅用于说明,可能无法运行.要了解如何正确使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我们可以使用我们刚创建的这个虚构类作为动态类型,如果该字段不存在则具有非常自定义的行为.
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!")
Run Code Online (Sandbox Code Playgroud)
ExpandoObject是一个完整的实现IDynamicMetaObjectProvider,.NET Framework团队为您做出了所有这些决定.如果您不需要任何自定义行为,并且您认为ExpandoObject对您来说足够好(90%的时间,ExpandoObject足够好),这将非常有用.例如,请参阅以下内容,对于ExpandoObject,如果动态成员不存在,设计人员会选择抛出异常.
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) { ... }
Run Code Online (Sandbox Code Playgroud)
总而言之,ExpandoObject只是一种预先选择的方式来扩展DynamicObject,其中某些动态调度行为可能对您有用,但可能不依赖于您的特定需求.
然而,DyanmicObject是一个帮助程序BaseType,它使简单易用的独特动态行为实现您自己的类型.
Bri*_*sen 35
根据C#语言规范dynamic是一种类型声明.即dynamic x意味着变量x具有类型dynamic.
DynamicObject是一种类型,使其易于实现IDynamicMetaObjectProvider,从而覆盖该类型的特定绑定行为.
ExpandoObject是一种类似于财产袋的类型.即,您可以在运行时向此类型的动态实例添加属性,方法等.