2013-05-30 2 views
5

Как сравнить свойства двух объектов, чтобы определить, изменились ли какие-либо свойства? У меня есть объект Patient с рядом свойств. У меня есть второй объект, UpdatedPatient, который может иметь разные значения. В настоящее время я использую следующие для каждого свойства:Как сравнить свойства двух объектов?

if (exPt.Id!= pt.Id) 
{ 
    exPt.Id = pt.Id; 
    PatientChanged = true; 
} 

После того как все свойства проверяются, если PatientChanged флаг true, пациент обновляется. Да, это работает, но я сомневаюсь, если это самое эффективное решение.

+0

Вы можете использовать этот пример из аналогичного вопроса. http://stackoverflow.com/questions/957783/loop-through-an-objects-properties-in-c-sharp – Bearcat9425

+2

В чем заключен контекст? Например, многие фреймворки и шаблоны позволят вам внедрить 'INotifyPropertyChanged' и подписаться на события, если вы хотите получать информацию об изменениях данных. Конечно, это не устраняет вашу проблему кодирования, но в зависимости от того, что вы делаете, возможно, вам стоит изучить ее. –

ответ

9

Да, это работает, но я задаю вопрос, если это самое эффективное решение.

Это, скорее всего, наиболее эффективное решение с точки зрения эффективности работы.

После того как все свойства проверяются, если PatientChanged флаг верно, пациент обновляется

Вы могли бы ускорить этот процесс, если вы короткий Curcuit - как только проверяется любой собственности и PatientChanged - true, вы знаете, что вам нужно обновить, чтобы вы могли пропустить другие проверки.

Чтобы написать меток, чтобы сделать это, вы можете использовать Reflection. Однако это будет гораздо менее эффективным с точки зрения производительности, но может устранить необходимость записи этих проверок для всех ваших типов, что может повысить эффективность разработки.

+0

+1 для короткого замыкания –

5

Я допрошу, если это самое эффективное решение.

Ответ зависит от того, как вы измеряете эффективность.

  • С точки зрения циклов процессора, это самый эффективный способ
  • С точки зрения усилий по обслуживанию, методы, основанные на отражении бы оказаться более эффективным.

Возможно, вы захотите построить гибридное решение LINQ/Reflection, чтобы получить приемлемую эффективность и сохранить ремонтопригодность: используйте отражение, чтобы получить все свои свойства, которые вам нужно сравнить, постройте дерево выражений LINQ, которое сравнивает их по один, скомпилируйте его как лямбда и используйте результирующий функтор для сравнения эффективности CPU.

Вот пример реализации гибридного подхода:

public static Func<T,T,bool> MakeComparator<T>() { 
    var lhs = Expression.Parameter(typeof (T)); 
    var rhs = Expression.Parameter(typeof (T)); 
    var allPropChecks = typeof(T) 
     .GetProperties() 
     .Where(p => p.CanRead && p.GetIndexParameters().Length == 0) 
     .Select(p => Expression.Equal(Expression.Property(lhs, p), Expression.Property(rhs, p))) 
     .ToList(); 
    Expression compare; 
    if (allPropChecks.Count == 0) { 
     return (a,b) => true; // Objects with no properties are the same 
    } else { 
     compare = allPropChecks[0]; 
     compare = allPropChecks 
      .Skip(1) 
      .Aggregate(compare, Expression.AndAlso); 
    } 
    return (Func<T, T, bool>)Expression.Lambda(compare, new[] { lhs, rhs }).Compile(); 
} 

С помощью этого метода в руке, вы можете выполнять сравнение, как это:

class Point3D { 
    public int X { get; set; } 
    public int Y { get; set; } 
    public int Z { get; set; } 
} 
... 
// Construct sample objects 
var p1 = new Point3D { X = 1, Y = 2, Z = 3}; 
var p2 = new Point3D { X = 1, Y = 2, Z = 3 }; 
var p3 = new Point3D { X = 1, Y = 3, Z = 1 }; 
// Get a comparator 
var cmp = MakeComparator<Point3D>(); 
// Use the comparator to compare objects to each other 
Console.WriteLine(cmp(p1, p2)); 
Console.WriteLine(cmp(p2, p3)); 

Вот demo of this approach on ideone.

Обратите внимание, что эта реализация довольно упрощена. Он использует == для всех атрибутов, а не для Equals, где это необходимо.Вы можете расширить его, сделав линию 7 более сложной.

+0

+1 много чего здесь;) –

0

Если вы сделали exPt struct вместо класса, то его метод .Equals будет сравнивать каждое из полей, а не сравнение ссылок.

+1

Это правда, но вы обычно не должны использовать по умолчанию 'Equals()' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' отражение). – svick

+0

Правда. Это быстро и просто кодировать, но не обязательно выполнять. – Deeko

Смежные вопросы