使用反射比较对象属性

Kum*_*mar 5 c# asp.net reflection

我有两个类Address和Employee如下:

 public class Address
{
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

   public class Employee
    {
        public string FirstName { get; set; }
        public string MiddleName { get; set; }
        public string LastName { get; set; }
        public Address EmployeeAddress { get; set; }
    }
Run Code Online (Sandbox Code Playgroud)

我有两个员工实例如下:

    var emp1Address = new Address();
    emp1Address.AddressLine1 = "Microsoft Corporation";
    emp1Address.AddressLine2 = "One Microsoft Way";
    emp1Address.City = "Redmond";
    emp1Address.State = "WA";
    emp1Address.Zip = "98052-6399";

    var emp1 = new Employee();
    emp1.FirstName = "Bill";
    emp1.LastName = "Gates";
    emp1.EmployeeAddress = emp1Address;


    var emp2Address = new Address();
    emp2Address.AddressLine1 = "Gates Foundation";
    emp2Address.AddressLine2 = "One Microsoft Way";
    emp2Address.City = "Redmond";
    emp2Address.State = "WA";
    emp2Address.Zip = "98052-6399";

    var emp2 = new Employee();
    emp2.FirstName = "Melinda";
    emp2.LastName = "Gates";
    emp2.EmployeeAddress = emp2Address;
Run Code Online (Sandbox Code Playgroud)

现在,我该如何编写一个方法来比较这两个雇员并返回具有不同值的属性列表.所以在这个例子中我希望结果是FirstName和Address.AddressLine1.

Osk*_*lin 13

就像LBushskin说的那样,你不必这样做.这不是最快的方法!如果你想购买,试试这个:

    public static List<PropertyInfo> GetDifferences(Employee test1, Employee test2)
    {
        List<PropertyInfo> differences = new List<PropertyInfo>();
        foreach (PropertyInfo property in test1.GetType().GetProperties())
        {
            object value1 = property.GetValue(test1, null);
            object value2 = property.GetValue(test2, null);
            if (!value1.Equals(value2))
            {
                differences.Add(property);
            }
        }
        return differences;
    }
Run Code Online (Sandbox Code Playgroud)


LBu*_*kin 7

您不一定需要反射来执行比较。您可以编写一个比较器类,它采用 Employee 或 Address 的两个实例,并比较每个应该匹配的字段。对于任何不匹配的,您可以PropertyInfo向某个列表添加一个字符串(或)元素以返回给调用者。

返回 a PropertyInfoMemberInfo还是仅返回字符串取决于调用者需要对结果做什么。如果您确实需要访问包含差异的字段,PropertyInfo/MemberInfo可能会更好 - 但仅报告差异字符串可能就足够了。

反射的主要价值是编写一个通用对象比较器,它可以采用任何类型对象的两个实例并比较它们的公共字段和属性。这有助于避免一遍又一遍地编写重复的比较代码 - 但您的情况似乎并非如此。


Mir*_*kus 5

这是基于 Oskar Kjellin 的awnser的通用递归解决方案。

我也发布了这个代码作为要点,所以你可以检查最新版本或 star/clone/fork :)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

protected List<KeyValuePair<Type, PropertyInfo>> RecrusiveReflectionCompare<T>(T first, T second)
        where T : class
    {
        var differences = new List<KeyValuePair<Type, PropertyInfo>>();

        var parentType = first.GetType();

        void CompareObject(object obj1, object obj2, PropertyInfo info)
        {
            if (!obj1.Equals(obj2))
            {
                differences.Add(new KeyValuePair<Type, PropertyInfo>(parentType, info));
            }
        }

        foreach (PropertyInfo property in parentType.GetProperties())
        {
            object value1 = property.GetValue(first, null);
            object value2 = property.GetValue(second, null);

            if (property.PropertyType == typeof(string))
            {
                if (string.IsNullOrEmpty(value1 as string) != string.IsNullOrEmpty(value2 as string))
                {
                    CompareObject(value1, value2, property);
                }
            }
            else if (property.PropertyType.IsPrimitive)
            {
                CompareObject(value1, value2, property);
            }
            else
            {
                if (value1 == null && value2 == null)
                {
                    continue;
                }

                differences.Concat(RecrusiveReflectionCompare(value1, value2));
            }
        }
        return differences;
    }
Run Code Online (Sandbox Code Playgroud)