我想知道下面的最佳方法
我有一个.NET Web应用程序,我正在更改我正在使用的ORM提供程序。为此,我创建了一个新的解决方案并删除了以前的ORM并实现了我的新解决方案。由于有许多现有的屏幕可以与之前的ORM一起工作,我想确保两个ORMS都返回相同的对象。由于这些是在两个单独的VS slns中,因此有一种简单的方法可以将所有相同属性加载到对象图上的复杂对象进行比较。我可以设置一个断点并手动比较它们但我真的不想这样做吗?
答案 0 :(得分:0)
如果这是出于测试目的,您可以使用FluentAssertions
进行检查。
以下代码声明了两个不相关的类型,ClassA
和ClassB
,它们包含两个名为A
和B
的嵌套类,但类型不同。
因此,包含类和嵌套类是不相关的类型,但成员的名称是相同的,对于嵌套类,属性的类型是相同的。
您可以使用FluentAssertions
来测试两个实例classA
和classB
是否相同 - 即使它们的类型不同 - 如下所示:
using System;
using FluentAssertions;
namespace Demo
{
class ClassA
{
public NestedClassA A;
public NestedClassB B;
}
class NestedClassA
{
public string S;
public int I;
}
class NestedClassB
{
public char C;
public double D;
}
class ClassB
{
public NestedClassC A;
public NestedClassD B;
}
class NestedClassC
{
public string S;
public int I;
}
class NestedClassD
{
public char C;
public double D;
}
internal class Program
{
private static void Main()
{
var nestedA = new NestedClassA {I = 1, S = "1"};
var nestedB = new NestedClassB {C = '1', D = 1};
var nestedC = new NestedClassC { I = 1, S = "1" };
var nestedD = new NestedClassD { C = '1', D = 1 };
var classA = new ClassA {A = nestedA, B = nestedB};
var classB = new ClassB {A = nestedC, B = nestedD};
classA.ShouldBeEquivalentTo(classB); // Passes
classB.ShouldBeEquivalentTo(classA); // Passes
classB.B.D = 2; // Now the two objects do not contain equivalent data.
classA.ShouldBeEquivalentTo(classB); // Fails.
}
}
}
答案 1 :(得分:0)
所以我猜这并不像实现IEquatable
接口那么简单,而是使用它来直接比较你的实例。您必须意识到实施正确的比较方法将是最快的方法。
但是有更慢,更灵活的方式。我想你想做的是:
只有一种方法可以做到这一点。这是问题System.Reflection
。请注意,此解决方案将比使用已知类型的所有解决方案慢得多。
所以你需要你的ComplexEquals
功能。
public static bool ComplexEquals(object obj1, object obj2)
{
if (obj1 == null && obj2 == null) return true;
if (obj1 == null || obj2 == null) return false;
var obj1Class = obj1.GetType();
var obj2Class = obj2.GetType();
/* Get the instance fields (all of them) of both classes. */
var obj1Fields = obj1Class.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
var obj2Fields = obj2Class.GetFields(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public);
var checkedFields = new HashSet<String>();
foreach (var obj1Field in obj1Fields)
{
var fieldName = obj1Field.Name;
checkedFields.Add(fieldName);
var obj2Field = obj2Fields.Where(f => f.Name == fieldName).SingleOrDefault();
if (obj2Field == null) return false;
if (obj1Field.FieldType == obj2Field.FieldType && !(obj1Field.GetValue(obj1).Equals(obj2Field.GetValue(obj2)))) return false;
}
if (obj2Fields.Any(f => !checkedFields.Contains(f.Name))) return false;
return true;
}
这是一个简单的版本,它依赖于从未知函数内的第一级开始的Equals
函数。这可能就足够了。但我认为这是一个可以在需要时扩展的起点。