这种在 C# 中比较两个对象的实现是否可以快速运行?
Will this implementation of comparing two objects in C# work quickly?
我创建了一个比较两个对象的实现。
IEquatable 界面不适合我,因为我需要一个不匹配的特定属性和值的列表。
这样的实施会很快奏效吗?或者有什么我不知道的现成的解决方案?
这是一个正在比较的对象的示例
public class Person
{
public string Name { get; set; }
public DateTime DoB { get; set; }
}
这是用于获取 属性 名称的附加扩展名
public static class ExpressionExtensions
{
public static string GetMemberName(this Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.MemberAccess:
return ((MemberExpression)expression).Member.Name;
case ExpressionType.Convert:
return GetMemberName(((UnaryExpression)expression).Operand);
default:
throw new NotSupportedException($"Expression type {expression.NodeType} not supported!");
}
}
}
这里是比较底class
public abstract class CompareBase<TEntity1, TEntity2>
where TEntity1 : class
where TEntity2 : class
{
public CompareBase(TEntity1 entity1, TEntity2 entity2)
{
_entity1 = entity1;
_entity2 = entity2;
Compare();
}
protected TEntity1 _entity1 { get; set; }
protected TEntity2 _entity2 { get; set; }
protected abstract void Compare();
protected void CompareFields(Expression<Func<TEntity1, object>> fieldExp1, Expression<Func<TEntity2, object>> fieldExp2)
{
var fieldVal1 = fieldExp1.Compile()(_entity1);
var fieldVal2 = fieldExp2.Compile()(_entity2);
if (!fieldVal1.Equals(fieldVal2))
{
Diff.Add($"Field {typeof(TEntity1).Name}.{fieldExp1.Body.GetMemberName()}={fieldVal1} != field {typeof(TEntity2).Name}.{fieldExp2.Body.GetMemberName()}={fieldVal2}");
}
}
public List<string> Diff { get; set; } = new List<string>();
}
这里是继承的class进行比较
public class PersonCompare : CompareBase<Person, Person>
{
public PersonCompare(Person entity1, Person entity2) : base(entity1, entity2) { }
protected override void Compare()
{
CompareFields(x => x.Name, x => x.Name);
CompareFields(x => x.DoB, x => x.DoB);
}
}
这是一个用法示例
var boy = new Person
{
Name = "Peter",
DoB = new DateTime(2000, 7, 10)
};
var girl = new Person
{
Name = "Sarah",
DoB = new DateTime(2001, 1, 12)
};
var compare = new PersonCompare(boy, girl);
compare.Diff.ForEach(x => System.Console.WriteLine(x));
我创建了一个比较两个对象的实现。
IEquatable 界面不适合我,因为我需要一个不匹配的特定属性和值的列表。
这样的实施会很快奏效吗?或者有什么我不知道的现成的解决方案?
这是一个正在比较的对象的示例
public class Person
{
public string Name { get; set; }
public DateTime DoB { get; set; }
}
这是用于获取 属性 名称的附加扩展名
public static class ExpressionExtensions
{
public static string GetMemberName(this Expression expression)
{
switch (expression.NodeType)
{
case ExpressionType.MemberAccess:
return ((MemberExpression)expression).Member.Name;
case ExpressionType.Convert:
return GetMemberName(((UnaryExpression)expression).Operand);
default:
throw new NotSupportedException($"Expression type {expression.NodeType} not supported!");
}
}
}
这里是比较底class
public abstract class CompareBase<TEntity1, TEntity2>
where TEntity1 : class
where TEntity2 : class
{
public CompareBase(TEntity1 entity1, TEntity2 entity2)
{
_entity1 = entity1;
_entity2 = entity2;
Compare();
}
protected TEntity1 _entity1 { get; set; }
protected TEntity2 _entity2 { get; set; }
protected abstract void Compare();
protected void CompareFields(Expression<Func<TEntity1, object>> fieldExp1, Expression<Func<TEntity2, object>> fieldExp2)
{
var fieldVal1 = fieldExp1.Compile()(_entity1);
var fieldVal2 = fieldExp2.Compile()(_entity2);
if (!fieldVal1.Equals(fieldVal2))
{
Diff.Add($"Field {typeof(TEntity1).Name}.{fieldExp1.Body.GetMemberName()}={fieldVal1} != field {typeof(TEntity2).Name}.{fieldExp2.Body.GetMemberName()}={fieldVal2}");
}
}
public List<string> Diff { get; set; } = new List<string>();
}
这里是继承的class进行比较
public class PersonCompare : CompareBase<Person, Person>
{
public PersonCompare(Person entity1, Person entity2) : base(entity1, entity2) { }
protected override void Compare()
{
CompareFields(x => x.Name, x => x.Name);
CompareFields(x => x.DoB, x => x.DoB);
}
}
这是一个用法示例
var boy = new Person
{
Name = "Peter",
DoB = new DateTime(2000, 7, 10)
};
var girl = new Person
{
Name = "Sarah",
DoB = new DateTime(2001, 1, 12)
};
var compare = new PersonCompare(boy, girl);
compare.Diff.ForEach(x => System.Console.WriteLine(x));