我已经看到了一些类似的线程,但没有一个可以回答我的问题,我现在不得不问。
我有两个对象,一个名为客户,另一个是一个名为 customerDto 的数据传输对象。
客户:
public partial class Customer
{
[DataMember]
public int Id { get; set;}
[DataMember]
public string Title { get; set;}
[DataMember]
public string FirstName { get; set;}
[DataMember]
public string Middle { get; set;}
[DataMember]
public string LastName { get; set;}
[DataMember]
public string Email { get; set;}
[DataMember]
public string HomePhone { get; set;}
[DataMember]
public string MobilePhone { get; set;}
[DataMember]
public string AddressLine1 { get; set;}
[DataMember]
public string AddressLine2 { get; set;}
[DataMember]
public string PostCode { get; set;}
[DataMember]
public DateTime? DateOfBirth { get; set;}
[DataMember][DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public string FullName { get; private set;}
}
public partial class Customer
{
public virtual ICollection<DeliveryDetail> DeliveryDetails { get; set; }
public virtual ICollection<Order> Order { get; set; }
}
客户Dto:
public class CustomerDto : ICloneable
{
public int Id { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string PostCode { get; set; }
public string Title { get; set; }
public string Email { get; set; }
public string HomePhone { get; set; }
public string MobilePhone { get; set; }
public DateTime? DateOfBirth { get; set; }
}
我需要比较它们共享的属性,但我不想写多行 if 语句,因为这很混乱。有没有办法做到这一点?
我只需要看看它们共享的任何属性是否存在差异。如果一个不同,那么我们可以继续前进并更新客户。
提前谢谢。
我认为您在这里寻找的是使用反射的 foreach 循环。
Customer customer; // assume its initialized
CustomerDto custDTO;
var recordsAreDifferent = false;
foreach (var prop in custDTO.GetType().GetProperties())
{
PropertyInfo customerProperty = customer.GetType().GetProperty(prop.name);
if(customerProperty == null) {continue;}
if(!prop.GetValue(custDTO, null).Equals(customerProperty.GetValue(customer, null)) {
recordsAreDifferent = true;
}
}
您可以考虑实现 IComparable 接口和实现 CompareTo(Object obj( 方法的客户类。
或
实现 IEquatable 接口
您可以在使用反射的泛型方法中执行此操作:
public static bool CompareMatchingProperties<TLeft,TRight>(TLeft lhs, TRight rhs) {
var allLeft = typeof(TLeft).GetProperties().ToDictionary(p => p.Name);
var allRight = typeof(TRight).GetProperties().ToDictionary(p => p.Name);
foreach (var name in allLeft.Keys.Intersect(allRight.Keys)) {
if (!object.Equals(allLeft[name].GetValue(lhs), allRight[name].GetValue(rhs))) {
return false;
}
}
return true;
}
这个想法是从两端的类型中获取所有公共属性(参见allLeft
和allRight
字典(,构造它们名称的交集(allLeft.Keys.Intersect(allRight.Keys)
循环中(,从每个被比较的对象(allLeft[name].GetValue(lhs)
和allRight[name].GetValue(rhs)
(中获取属性值,并使用object.Equals
进行比较。
演示。
使用任何此类方法要记住的一件事是,比较两个没有任何共同属性的对象的结果将返回 true
.可以通过要求至少匹配一对属性来解决此问题。
你可以编写一个特定的方法,如下所示:
public bool UpdateCustomer(Customer customer, CustomerDto dto)
{
//Get properties from both objects
System.Reflection.PropertyInfo[] customerProperties = customer.GetType().GetProperties();
System.Reflection.PropertyInfo[] dtoProperties = dto.GetType().GetProperties();
//Get properties that have the same name on both objects
var propertiesToCompare = from customerProp in customerProperties
join dtoProp in dtoProperties
on customerProp.Name equals dtoProp.Name
select customerProp;
foreach (var property in propertiesToCompare)
{
if (property.GetValue(customer, null) != property.GetValue(dto, null))
return true;
}
return false;
}
您可以从两个对象获取所有属性,然后检查它们共享的任何属性是否具有不同的值。如果这样做,该方法将返回 true。如果不是,则返回 false。
我了解,CustomerDto 是 DB 的实体,客户是客户的合同。如何将客户类型转换为客户Dto并比较客户Dto的两个对象?
如果您需要比较 2 个对象并且正在使用 C#,我认为这样做的一个好方法是使用运算符重载。要做到这一点,请考虑以下几点:
- 所有运算符重载都是静态方法
- 您有一元运算符和二进制运算符。
- 要重载比较器运算符(<<、>>、==、!=、>、<、>=、<=(,您必须重载相反的运算符。(例如,如果你加载">"也必须重载"<"(
- 您必须在所涉及的对象的某些类中声明它。
辛塔克西斯是这样的。
public static ReturnValue operator+(Object a, Object b)
{
// Comparison logic
return value;
}
对于您的特定问题,您应该执行以下操作:
public static Boolean operator==(Customer cust, CustomerDto custDto)
{
//Here you code a for or foreach o whatever you want to compare
//cust with custDto and return true is you found a difference or false
//if there are no differences
return booleanValue;
}
然后加载 != 运算符。要重用代码,您可以调用其他比较器:
public static Boolean operator!=(Customer cust, CustomerDto custDto)
{
return !(cust == custDto);
}
因此,在您的代码中,您可以使用如下所示的内容检查一个 Customer 对象和一个 CustomerDto 对象之间是否存在差异:
if (customerObject == customerDtoObject)
{
//Whatever you want
}
希望这对您有所帮助。