Сравнение Свойств объектов с помощью отражения

У меня есть два класса Адрес и Сотрудник следующим образом:

 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; }
    }

У меня есть два экземпляра сотрудника следующим образом:

    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;

Теперь, как я могу записать метод, который сравнивает эти двух сотрудников и возвращает список свойств, которые имеют различные значения. Таким образом в этом примере я хотел бы, чтобы результатом был FirstName и Адрес. AddressLine1.

5
задан Kumar 23 March 2010 в 18:03
поделиться

4 ответа

Вам не обязательно нужно отражение для выполнения сравнения. Вы можете написать класс компаратора, который принимает два экземпляра Employee или Address и сравнивает каждое поле, которое должно совпадать. Для любых несоответствий вы можете добавить строку (или PropertyInfo ) элемент в некоторый список, чтобы вернуться к вызывающему.

Возвращаете ли вы PropertyInfo , MemberInfo или просто строку, зависит от того, что вызывающей стороне нужно делать с результатом. Если вам действительно нужно просмотреть поля, содержащие различия, PropertyInfo / MemberInfo может быть лучше, но для того, чтобы просто сообщить о различиях, вероятно, будет достаточно строки.

Основная ценность отражения заключается в написании средства сравнения объектов общего назначения , которое могло бы принимать два экземпляра любого объекта и сравнивать их общедоступные поля и свойства. Это помогает избежать повторения повторяющегося кода сравнения снова и снова - но это не похоже на тот случай, в котором вы находитесь.

2
ответ дан 18 December 2019 в 10:43
поделиться
public IEnumerable<PropertyInfo> GetNotEqualsProperties(Employee emp1, Employee emp2)
{
    Type employeeType = typeof (Employee);
    var properies = employeeType.GetProperties();
    foreach (var property in properies)
        if(!property.GetValue(emp1, null).Equals(property.GetValue(emp2, null))) //TODO: check for null
            yield return property;
}

А для сложных свойств вы должны переопределить метод Equals

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 override bool Equals(object obj)
    {
        if (obj as Address == null)
            return false;
        return ((Address) obj).AddressLine1.Equals(AddressLine1);
    }
}
0
ответ дан 18 December 2019 в 10:43
поделиться

Не нужно размышлять. Конечно, этот пример возвращает строку с именами свойств ... если вам нужен реальный объект PropertyInfo , все станет немного сложнее, но не намного.

public static IEnumerable<string> DiffEmployees
    (Employee one, Employee two)
{
    if(one.FirstName != two.FirstName)
        yield return "FirstName";
    if(one.LastName != two.LastName)
        yield return "LastName";
    if(one.Address.AddressLine1 != two.Address.AddressLine1)
        yield return "Address.AddressLine1";

    // And so on.
}
-1
ответ дан 18 December 2019 в 10:43
поделиться

Как сказал Л.Бушскин, вам не нужно этого делать. Это не самый быстрый способ! Купите, если хотите, попробуйте следующее:

    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;
    }
13
ответ дан 18 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: