有没有办法在 C# 中比较两个不同类型的对象



我已经看到了一些类似的线程,但没有一个可以回答我的问题,我现在不得不问。

我有两个对象,一个名为客户,另一个是一个名为 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;
}

这个想法是从两端的类型中获取所有公共属性(参见allLeftallRight字典(,构造它们名称的交集(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
}

希望这对您有所帮助。

相关内容

  • 没有找到相关文章

最新更新