Сравнивайте объекты в C#, но игнорируйте некоторые свойства объекта при сравнении

Я пытаюсь сравнить 2 объекта (предыдущий объект с текущим объектом), чтобы проверить равенство. Значения в предыдущем объекте и текущем объекте одинаковы, но UUID в текущем объекте изменяется. Я не хочу сравнивать UUID свойства, но хочу сравнить другое свойство предыдущего объекта с текущим объектом. Я использовал метод .equals в C#, но поскольку UUID в текущем объекте отличается, он возвращает false. Может ли кто-нибудь посоветовать мне, как я могу сравнить эти два объекта, игнорируя свойство: UUID, используя С# или пожалуйста, предложите метод сравнения двух объектов, игнорируя свойство UUID. Спасибо.

Я также пробовал использовать ToHashSet().SetEquals(это не подойдет, потому что потому что у меня много собственности в объекте)

Я использовал метод .equals в C#. Я также пробовал использовать ToHashSet().SetEquals(это не подойдет, потому что потому что у меня много собственности в объекте)

Ожидание: Метод C# будет принимать два параметра: предыдущий объект и текущий объект. Он будет игнорировать UUID свойства в объекте и сравнивать остальные свойства этих двух объектов.

или запрос C# linq, который будет игнорировать UUID свойства в объекте и сравнивать оставшиеся свойства этих двух объектов.

Пожалуйста, найдите XML. Я назвал его «Предыдущий объект» и «Текущий объект».

Предыдущий объект

<Company>
<EmployeeDetails>
<Employee>
<UUID>111-111-111</UUID>
<Name>Albert</Name>
<Age>30</Age>
<Designation>Sales Manager</Designation>
</Employee>
<Employee>
<UUID>222-222-222</UUID>
<Name>John</Name>
<Age>35</Age>
<Designation>Production Manager</Designation>
</Employee>
</EmployeeDetails>
<EmployeeDetails>
<Employee>
<UUID>333-333-333</UUID>
<Name>Danny</Name>
<Age>40</Age>
<Designation>Network Engineer</Designation>
</Employee>
<Employee>
<UUID>444-444-444</UUID>
<Name>Marty</Name>
<Age>35</Age>
<Designation>Operations</Designation>
</Employee>
</EmployeeDetails>
</Company>

Текущий объект

<Company>
<EmployeeDetails>
<Employee>
<UUID>aaa-aaa-aaa</UUID>
<Name>Albert</Name>
<Age>30</Age>
<Designation>Sales Manager</Designation>
</Employee>
<Employee>
<UUID>bbb-bbb-bbb</UUID>
<Name>John</Name>
<Age>35</Age>
<Designation>Production Manager</Designation>
</Employee>
</EmployeeDetails>
<EmployeeDetails>
<Employee>
<UUID>ccc-ccc-ccc</UUID>
<Name>Danny</Name>
<Age>40</Age>
<Designation>Network Engineer</Designation>
</Employee>
<Employee>
<UUID>ddd-ddd-ddd</UUID>
<Name>Marty</Name>
<Age>35</Age>
<Designation>Operations</Designation>
</Employee>
</EmployeeDetails>
</Company>

class employee
{
string uuid;
string name;
int age;
string designation;
}

class EmployeeDetails
{
List<employee> employee;
}

class Company
{
List<EmployeeDetails> EmployeeDetails;
}

вы можете использовать собственный EqualityComparer, такой как этот, который я только что написал

Ivan Petrov 04.08.2024 12:17

Обратите внимание, что вы можете использовать xmltocsharp.azurewebsites.net для создания классов C# из XML-кода.

John Alexiou 04.08.2024 21:48
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
95
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Всегда сложно сравнивать такие сложные объекты, как вы. но вот код для сравнения объектов со списком игнорируемых свойств. Вы можете передать строку «UUID», чтобы игнорировать свойство UUID, и оно не будет проверять это свойство в объекте.

public static bool AreEqual<T>(T obj1, T obj2, params string[] propertiesToIgnore)
{
    if (ReferenceEquals(obj1, obj2)) return true;
    if (obj1 == null || obj2 == null) return false;
    if (obj1.GetType() != obj2.GetType()) return false;

    var ignoredProperties = new HashSet<string>(propertiesToIgnore);

    foreach (var property in obj1.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        if (ignoredProperties.Contains(property.Name)) continue;

        var value1 = property.GetValue(obj1);
        var value2 = property.GetValue(obj2);

        if (!AreValuesEqual(value1, value2, propertiesToIgnore)) return false;
    }

    return true;
}

private static bool AreValuesEqual(object value1, object value2, params string[] propertiesToIgnore)
{
    if (ReferenceEquals(value1, value2)) return true;
    if (value1 == null || value2 == null) return false;

    if (value1.GetType() != value2.GetType()) return false;

    if (value1 is IEnumerable && !(value1 is string))
    {
        var collection1 = ((IEnumerable)value1).Cast<object>().ToList();
        var collection2 = ((IEnumerable)value2).Cast<object>().ToList();
        return AreCollectionsEqual(collection1, collection2, propertiesToIgnore);
    }

    return value1.Equals(value2);
}

private static bool AreCollectionsEqual(List<object> collection1, List<object> collection2, params string[] propertiesToIgnore)
{
    if (collection1.Count != collection2.Count) return false;

    for (int i = 0; i < collection1.Count; i++)
    {
        if (!AreEqual(collection1[i], collection2[i], propertiesToIgnore)) return false;
    }

    return true;
}

и вот ссылка , чтобы проверить рабочий код. Пожалуйста, дайте мне знать, работает ли это решение для вас.

это работает, но мы используем отражение при каждом вызове. Мы можем использовать собственный EqualityComparer, который по-прежнему использует отражение, но создает делегаты из выражений, которые вызываются при каждом вызове Equals -> скрипке

Ivan Petrov 04.08.2024 12:20

Спасибо, Утсав. Я могу сравнить 2 объекта согласно предоставленному вами коду.

Kar B 05.08.2024 00:26

Просто используйте простой метод записи:

bool AreEmployeesEqual(Employee e1, Employee e2)
    => e1.name == e2.name && e1.age == e2.age && e1.designation == e2.designation;

Вы можете переопределить Equals и GetHashCode для класса Employee:

public override bool Equals(object obj)
{
    var item = obj as Employee;

    if (item == null)
    {
        return false;
    }

    return this.name.Equals(item.name) && 
        this.age.Equals(item.age) && 
        this.designation.Equals(item.designation);
}

public override int GetHashCode()
{
    unchecked
    {
        int hash = 17;
        hash = hash * 31 + age.GetHashCode();
        hash = hash * 31 + name.GetHashCode();
        hash = hash * 31 + designation.GetHashCode();
        return hash;
    }
}

Использованная литература:

Спасибо, Михал. Решение, которое вы предоставили, работает для меня. Но у меня более 30 объектов недвижимости в классе модели, и их число может вырасти.

Kar B 05.08.2024 00:24

Другие вопросы по теме