У меня есть два класса Адрес и Сотрудник следующим образом:
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.
Вам не обязательно нужно отражение для выполнения сравнения. Вы можете написать класс компаратора, который принимает два экземпляра Employee или Address и сравнивает каждое поле, которое должно совпадать. Для любых несоответствий вы можете добавить строку (или PropertyInfo
) элемент в некоторый список, чтобы вернуться к вызывающему.
Возвращаете ли вы PropertyInfo
, MemberInfo
или просто строку, зависит от того, что вызывающей стороне нужно делать с результатом. Если вам действительно нужно просмотреть поля, содержащие различия, PropertyInfo / MemberInfo
может быть лучше, но для того, чтобы просто сообщить о различиях, вероятно, будет достаточно строки.
Основная ценность отражения заключается в написании средства сравнения объектов общего назначения , которое могло бы принимать два экземпляра любого объекта и сравнивать их общедоступные поля и свойства. Это помогает избежать повторения повторяющегося кода сравнения снова и снова - но это не похоже на тот случай, в котором вы находитесь.
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);
}
}
Не нужно размышлять. Конечно, этот пример возвращает строку с именами свойств ... если вам нужен реальный объект 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.
}
Как сказал Л.Бушскин, вам не нужно этого делать. Это не самый быстрый способ! Купите, если хотите, попробуйте следующее:
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;
}