假设以下课程:
public class MyEntity
{
public string FirstName;
public string LastName;
}
我想比较MyEntity
的两个实例,并创建一个新的MyEntity
实例,该实例仅包含其他两个实例之间的值差异。相等的属性将在新对象中生成null
值。
例如,我想要以下代码:
MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" };
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" };
MyEntity diffEntity = CreateDiffEntity(entity1, entity2); // TODO
得到以下diffEntity
值:
{
FirstName: null,
LastName: "The Great"
}
我们可以假设所有属性都可以为空。
如果值不匹配,新对象应包含第二个对象属性的值。
请假设我有许多类型的实体,具有不同的属性定义
所以我需要一个可以在MyEntity
以外的其他类类型上使用的解决方案,并且在将新属性添加到类中时不需要更改。
最终目标是使客户端移动应用程序能够将仅包含对实体所做更改的DTO发送到ASP.NET MVC WebAPI服务器应用程序。
如何妥善完成?
答案 0 :(得分:4)
您可以使用Reflection来解决此问题。它的基本要点是:
public void Compare(object first,object second, object result)
{
Type t = first.GetType();
PropertyInfo[] propertyInfoList = t.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfoList)
{
object value1= propertyInfo.GetValue(first, null);
object value2 = propertyInfo.GetValue(second, null);
if (value1 != value2)
{
propertyInfo.SetValue(result, value1, null);
}
else
{
propertyInfo.SetValue(result, null, null);
}
}
}
然后像这样使用它:
MyType result = new MyType();
Compare(object1,object2, result);
它可以用作扩展方法或其中一个实体的成员。
答案 1 :(得分:2)
整个方法存在一个很大的问题:你无法将任何内容设置为null
。您可能只是发送完整的实体,或者,如果您的接口只允许编辑属性的子集,请为每个接口创建一个DTO,只包含可能发生的更改。
无论如何,仅仅因为它已经成熟,可以进行一些简单的改进,这是一个基于BrianV's solution的通用且略有修改的解决方案。 (使用object.Equals
代替!=
可以通过价值来比较事物,而不仅仅是他们的身份。
public T Compare<T>(T first, T second) where T : new()
{
T result = new T();
Type t = typeof(T);
PropertyInfo[] propertyInfoList = t.GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfoList)
{
object value1 = propertyInfo.GetValue(first, null);
object value2 = propertyInfo.GetValue(second, null);
if (!object.Equals(value1, value2))
propertyInfo.SetValue(result, value2, null);
}
return result;
}
使用它像:
MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" };
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" };
MyEntity diffEntity = Compare(entity1, entity2);
答案 2 :(得分:1)
你走了:
static public T CreateDiffEntity<T>(T entity1, T entity2) where T : new()
{
T result = new T();
foreach (var property in typeof(T).GetProperties())
{
var valuePropertyEntity1 = property.GetValue(entity1);
var valuePropertyEntity2 = property.GetValue(entity2);
if (!valuePropertyEntity1.Equals(valuePropertyEntity2))
property.SetValue(result, valuePropertyEntity2);
else
property.SetValue(result, null);
}
return result;
}
答案 3 :(得分:0)
您可以像这样解决您的问题:
public MyEntity CreateDiffEntity(MyEntity entity1, MyEntity entity2) {
MyEntity diff = new MyEntity();
diff.FirstName = !entity1.FirstName.equals(entity2.FirstName) ? entity2.FirstName : string.Empty;
diff.LastName = !entity1.LastName.equals(entity2.LastName) ? entity2.LastName : string.Empty;
return diff;
}
答案 4 :(得分:0)
您可以在对象初始值设定项
中执行此操作MyEntity entity1 = new MyEntity() { FirstName = "Jon", LastName = "Doh" };
MyEntity entity2 = new MyEntity() { FirstName = "Jon", LastName = "The Great" };
MyEntity diffEntity = new MyEntity
{
FirstName = (entity1.FirstName == entity2.FirstName) ? null : entity2.FirstName,
LastName = (entity1.LastName == entity2.LastName) ? null : entity2.LastName
};