Я допрошу, если это самое эффективное решение.
Ответ зависит от того, как вы измеряете эффективность.
- С точки зрения циклов процессора, это самый эффективный способ
- С точки зрения усилий по обслуживанию, методы, основанные на отражении бы оказаться более эффективным.
Возможно, вы захотите построить гибридное решение 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 более сложной.
Вы можете использовать этот пример из аналогичного вопроса. http://stackoverflow.com/questions/957783/loop-through-an-objects-properties-in-c-sharp – Bearcat9425
В чем заключен контекст? Например, многие фреймворки и шаблоны позволят вам внедрить 'INotifyPropertyChanged' и подписаться на события, если вы хотите получать информацию об изменениях данных. Конечно, это не устраняет вашу проблему кодирования, но в зависимости от того, что вы делаете, возможно, вам стоит изучить ее. –