Есть 2 объекта одинакового типа.
В этом типе порядка 30 свойств.
Как найти отличающиеся по значениям свойства этих 2 объектов?
Хочется без рефлексии и без сравнения всех полей последовательно.
Верю в либы и что чего-то не знаю)
Здравствуйте, e.thrash, Вы писали:
ET>Есть 2 объекта одинакового типа. ET>В этом типе порядка 30 свойств.
ET>Как найти отличающиеся по значениям свойства этих 2 объектов? ET>Хочется без рефлексии и без сравнения всех полей последовательно. ET>Верю в либы и что чего-то не знаю)
Написать свой source code generator, который бы создавал класс расширение для данного типа с нужным методом сравнения (используя рефлексию конечно).
ET>>Как найти отличающиеся по значениям свойства этих 2 объектов? ET>>Хочется без рефлексии и без сравнения всех полей последовательно. ET>>Верю в либы и что чего-то не знаю)
NW>Написать свой source code generator, который бы создавал класс расширение для данного типа с нужным методом сравнения (используя рефлексию конечно).
Тут проблема сравнивать объекты свойств на уровне ReferenceEquals или содержимого свойств. Это же касается и массивов. То есть предварительно сортировать по содержимому или достаточно сравнивать по индексу. Сравнивать строки с учетом регистров или нет итд
Ну и защита от циклических ссылок
и солнце б утром не вставало, когда бы не было меня
Это же рефлексия. Вроде не подходит по условию задачи?
Perform a deep compare of any two .NET objects using reflection
Даже в AutoMapper компиляция expression tree используется, AFAIK.
Находится поиском вот такое вот готовое на том же принципе, но сам не использовал https://github.com/StevenGilligan/AutoCompare
Вообще я бы забил и сравнивал тупо вручную последовательно
Здравствуйте, e.thrash, Вы писали:
ET>Есть 2 объекта одинакового типа. ET>В этом типе порядка 30 свойств.
ET>Как найти отличающиеся по значениям свойства этих 2 объектов? ET>Хочется без рефлексии и без сравнения всех полей последовательно. ET>Верю в либы и что чего-то не знаю)
Здравствуйте, sergii.p, Вы писали:
SP>Здравствуйте, e.thrash, Вы писали:
ET>>Хочется без рефлексии и без сравнения всех полей последовательно.
SP>а как это теоретически возможно? Даже сравнение бинарных представлений уже забанено по условию. Похоже надо умерить аппетиты.
сравнение последовательно я имел ввиду не писать
if (obj1.name != obj2.name)
{
}
...
if (obj1.name30 != obj2.name30)
{
}
Здравствуйте, sergii.p, Вы писали:
ET>>Хочется без рефлексии и без сравнения всех полей последовательно.
SP>а как это теоретически возможно? Даже сравнение бинарных представлений уже забанено по условию. Похоже надо умерить аппетиты.
Макрос/шаблон времени компиляции например, через доступ к AST компилятора (но такого в C# пока не завезли вроде, а Немерле не нужен?), завезли только source code generators.
По ключевым словам нашлась вот такая жесть, но это не совсем про объекты, это про рекорды.
Здравствуйте, e.thrash, Вы писали:
ET>Есть 2 объекта одинакового типа. ET>В этом типе порядка 30 свойств.
ET>Как найти отличающиеся по значениям свойства этих 2 объектов? ET>Хочется без рефлексии и без сравнения всех полей последовательно. ET>Верю в либы и что чего-то не знаю)
Здравствуйте, e.thrash, Вы писали: ET>Есть 2 объекта одинакового типа. ET>В этом типе порядка 30 свойств. ET>Как найти отличающиеся по значениям свойства этих 2 объектов? ET>Хочется без рефлексии и без сравнения всех полей последовательно. ET>Верю в либы и что чего-то не знаю)
Можно "построить" компаратор для заданного типа и подсунуть в компаратор "перехватыватель", который в случае, когда сравнение вернуло `false`, что-то сделает.
Примерчик
using NCompare;
var comparer = new ComparerBuilder<MyValue>(new MyInterception())
.Add(item => item.Age) // Компаратор строится по System.Linq.Expression
.Add(item => item.Name, StringComparer.OrdinalIgnoreCase) // Можно задавать, как именно сравнивать каждое свойство, поэтому можно сравнивать и коллекции и всё, что угодно
.CreateEqualityComparer();
var value1 = new MyValue { Age = 7, Name = "X", };
var value2 = new MyValue { Age = 7, Name = "Y", };
if(!comparer.Equals(value1, value2)) {
Console.WriteLine("Look on Console why values are not equal.");
}//ifinternal sealed class MyValue
{
public int Age { get; init; }
public string Name { get; init; } = String.Empty;
}
internal sealed class MyInterception : IComparerBuilderInterception
{
public int InterceptCompare<T>(int value, T x, T y, ComparerBuilderInterceptionArgs<T> args) => value;
public int InterceptGetHashCode<T>(int value, T obj, ComparerBuilderInterceptionArgs<T> args) => value;
public bool InterceptEquals<T>(bool value, T x, T y, ComparerBuilderInterceptionArgs<T> args) {
if(!value) {
Console.WriteLine($"The comparison of following expression (`{args.ExpressionText}`) returned false: {nameof(x)}: {{{x}}}, {nameof(y)}: {{{y}}}");
}//ifreturn value;
}
}
Вывод:
The comparison of following expression (`item => item.Name`) returned false: x: {X}, y: {Y}
Help will always be given at Hogwarts to those who ask for it.