比较C#中的动态对象 [英] Comparing dynamic objects in C#

查看:178
本文介绍了比较C#中的动态对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

比较两个任意动态对象的最佳方法是什么?例如这两个对象。



Ie

  dynamic obj1 = new ExpandoObject(); 
obj1.Name =Marcus;
obj1.Age = 39;
obj1.LengthInMeters = 1.96;

动态obj2 = AMethodReturningADynamic();
obj2.Name =Marcus;
obj2.Age = 39;
obj2.LengthInMeters = 1.96;

Assert.AreEqual(obj1,obj2); //?还有一种方法可以将实际的属性及其值作为列表获取;?b

$ b?要从动态类型创建一个ExpandoObject?

解决方案

Microsoft API用于动态调用任意动态对象的方法和属性( IDynamicMetaObjectProvider)当您没有编译器的帮助时,不容易使用。您可以使用 Dynamitey (通过nuget)来简化此操作。它具有静态功能 Dynamic.InvokeGet 调用属性的getter只需一个目标和一个属性名称。



为了获取动态对象的属性列表,有一点点,因为动态对象必须支持它(如果它是一个DynamicObject,意味着实现GetDynamicMemberNames,Expando支持它,但随机IDynamicMetaObjectProvider可能不会,只返回一个空列表)。 Dynamitey有一个简化获取这些名称的方法, Dynamic.GetMemberNames



这两个函数都提供了通过属性比较许多任意动态对象所需的基本工具。

  // using System.Dynamic; 
//使用Dynamitey;
//使用System.Linq;

IEnumerable< string> list1 = Dynamic.GetMemberNames(obj1);
list1 = list1.OrderBy(m => m);
IEnumerable< string> list2 = Dynamic.GetMemberNames(obj2);
list2 = list2.OrderBy(m => m);

if(!list1.SequenceEqual(list2))
return false;

foreach(list1中的var memberName){
if(!Dynamic.InvokeGet(obj1,memberName).Equals(Dynamic.InvokeGet(obj2,memberName))){
return假;
}
}
返回true;

但是,如果它们只是您自己的DynamicObject子类,那么只需遵循典型的实施Equals的规则,与非动态的实际没有区别对象,只是比较你在内部使用的状态。


What is the best way to compare two arbitrary dynamic objects for equality? For example these two objects.

I.e.

dynamic obj1 = new ExpandoObject();
obj1.Name = "Marcus";
obj1.Age = 39;
obj1.LengthInMeters = 1.96;

dynamic obj2 = AMethodReturningADynamic();
obj2.Name = "Marcus";
obj2.Age = 39;
obj2.LengthInMeters = 1.96;

Assert.AreEqual(obj1, obj2); // ?

Or is there a way to get the actual properties and their values as lists? To create an ExpandoObject from a dynamic type for example?

解决方案

The Microsoft API's for dynamically invoking methods and propertys on arbitrary dynamic objects (IDynamicMetaObjectProvider) are not easy to use when you don't have the compiler's help. You can use Dynamitey (via nuget) to simplify this completely. It has a static function Dynamic.InvokeGet to call property's getters with just a target and a property name.

To get a list of properties of the dynamic object, there is a bit of a gotcha, as the dynamic object has to support it (if it's a DynamicObject that means implementing GetDynamicMemberNames, Expando supports it, but random IDynamicMetaObjectProvider may not and just return an empty list). Dynamitey has a method to simplifying getting those names as well, Dynamic.GetMemberNames.

Both of those two functions give you the basic tools necessary to compare many arbitrary dynamic objects via properties.

//using System.Dynamic;
//using Dynamitey;
//using System.Linq;

IEnumerable<string> list1 =Dynamic.GetMemberNames(obj1);
list1 = list1.OrderBy(m=>m);
IEnumerable<string> list2 =Dynamic.GetMemberNames(obj2);
list2 = list2.OrderBy(m=>m);

if(!list1.SequenceEqual(list2))
 return false;

foreach(var memberName in list1){
 if(!Dynamic.InvokeGet(obj1, memberName).Equals(Dynamic.InvokeGet(obj2,memberName))){
    return false;
 }
}
return true;

However, if they are just your own DynamicObject subclass then it'd be easier to just follow the typical rules for implementing Equals, there really is no difference from non-dynamic objects, and just compare what you are internally using for state.

这篇关于比较C#中的动态对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆