c# - 在 C# 中比较动态对象

标签 c# dynamic

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

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); // ?

或者有没有办法将实际属性及其值作为列表获取?例如,要从动态类型创建 ExpandoObject?

最佳答案

如果没有编译器的帮助,用于动态调用任意动态对象 (IDynamicMetaObjectProvider) 的方法和属性的 Microsoft API 并不容易使用。您可以使用 Dynamitey (通过 nuget)来完全简化这个。它有一个静态函数Dynamic.InvokeGet仅使用目标和属性名称调用属性的 getter。

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

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

//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;

但是,如果它们只是您自己的 DynamicObject 子类,那么遵循典型的 rules for implementing Equals 会更容易。 ,与非动态对象真的没有区别,只是比较你内部使用的状态。

关于c# - 在 C# 中比较动态对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7215835/

相关文章:

c# - 如何将 ScrollBar 添加到 Stackpanel

linq - 如何在 linq where 子句中使用字符串?

c# - LINQ2SQL 和 NHibernate,按计算列分组

c# - 为什么不能在 .NET 中定义通用索引器?

c# - 如何从表中选择所有 SQL 行(具有两列的唯一组合),其中相同的组合不在另一个表中

PHP mysql动态表(考勤表)

c++ - 在这种情况下我必须删除内存吗?

javascript - 逐行 <tr> 单独访问表数据 <td>

c# - 带有对象初始化器 NEST 5.x 的 Elasticsearch 嵌套动态查询

c# - DevExpress 日期选择器没有日期