问题源于数据库表的比较。假设我们将左行和左右行放在实例右侧的同一类型中。我们有许多桌子和各自的类型。
如何实现或多或少的通用例程,从而产生差异集合,例如
propertyName,leftValue,rightValue为每个这样的一对相同类型的实例。
除了通用的比较算法,因为leftValue和rightValue可以是任何东西(一对字符串或int或DateTime或Guid),如何将一个集合中的所有内容组合起来并不明显。
修改
class OneOfManyTypesBasedOnTableRow
{
Guid uid,
int anotherId,
string text1,
string text2,
DateTime date1,
DateTime date2
}
class AnotherOfManyTypesBasedOnTableRow
{
Guid uid,
int anotherId,
string text3,
string text4,
DateTime date3,
DateTime date4
}
//For type 1
OneOfManyTypesBasedOnTableRow Left = new Something().GetLeft() ;
OneOfManyTypesBasedOnTableRow Right = new Something().GetRight() ;
DiffCollection1 diff1 = comparer.GetDiffForOneOfManyTypesBasedOnTableRow ( Left , Right ) ;
//For type 2
AnotherOfManyTypesBasedOnTableRow Left = new SomethingElse().GetLeft() ;
AnotherOfManyTypesBasedOnTableRow Right = new SomethingElse().GetRight() ;
DiffCollection2 diff2 = comparer.GetDiffForAnotherOfManyTypesBasedOnTableRow ( Left , Right ) ;
我的问题是我不知道如何避免重复每种类型的相似代码。对象群可能没问题。但在diff方法中我必须编码
if Left.Text1.Equals ( Right.Text1 )
等在一种方法中
if Left.Text3.Equals ( Right.Text3 )
以其他方法等等
答案 0 :(得分:3)
不确定这是否正是您想要的,但此方法可以对匹配属性的两个对象进行浅层比较,并比较它们以查看它们是否相等。
private static bool DoObjectsMatch(object object1, object object2)
{
var props1 = object1.GetType()
.GetProperties()
.ToDictionary<PropertyInfo,string,object>(p => p.Name, p => p.GetValue(object1, null));
var props2 = object2.GetType()
.GetProperties()
.ToDictionary<PropertyInfo,string,object>(p => p.Name, p => p.GetValue(object2, null));
var query = from prop1 in props1
join prop2 in props2 on prop1.Key equals prop2.Key
select prop1.Value == null ? prop2.Value == null : prop1.Value.Equals(prop2.Value);
return query.Count(x => x) == Math.Max(props1.Count(), props2.Count());
}
使用此方法,您可以根据一个匹配的属性名称比较两个对象。例如:
class Thing
{
public int Id {get;set;}
public string Text{get;set;}
}
void Main()
{
var t1 = new Thing{ Id = 3, Text = "hi" };
var t2 = new Thing{ Id = 3, Text = "hi" };
var t3 = new Thing{ Id = 4, Text = "bye" };
Console.WriteLine(DoObjectsMatch(t1,t2)); // True
Console.WriteLine(DoObjectsMatch(t2,t3)); // False
}
答案 1 :(得分:1)
我创建了一个库来做这件事并提供一些额外的元数据。不幸的是,它依赖于MVC ModelMetadata
和DataAnnotations
来为非技术用户提供差异的“可读版本”。因此,它将使用您的DisplayName
作为属性而不是其实际属性名称。
但它确实提供了为您自己的用途获取diff的编程表示的能力,而不是使用“可读”扩展。
https://github.com/paultyng/ObjectDiff
给出如下对象:
var before = new
{
Property1 = "",
MultilineText = "abc\ndef\nghi",
ChildObject = new { ChildProperty = 7 },
List = new string[] { "a", "b" }
};
var after = new
{
Property1 = (string)null,
MultilineText = "123\n456",
NotPreviouslyExisting = "abc",
ChildObject = new { ChildProperty = 6 },
List = new string[] { "b", "c" }
};
可读的diff扩展输出类似于:
ChildObject - ChildProperty: '6', was '7'
List - [2, added]: 'c', was not present
List - [removed]: No value present, was 'a'
MultilineText:
-----
123
456
-----
was
-----
abc
def
ghi
-----
NotPreviouslyExisting: 'abc', was not present
但程序化差异会为您提供有关每个属性和列表项的信息,您可以使用它来做。
我计划将来拆分MVC要求,它是全部开源的,所以你可以随意破解它。如果不是完全符合您的需求,它可能是一个好的起点。