Создайте универсальный метод для использования EqualityComparer, который я определил для определенных типов

#c# #generics #collections #equality #iequalitycomparer

#c# #общие #Коллекции #равенство #iequalitycomparer

Вопрос:

У меня есть много объектов, в которых я хочу проверить, что списки этих объектов равны.

Для каждого объекта я определил EqualityComparer:

 public class BaseAssociatedEntity : BasePage
{
    protected IWebElement EntityElement;
    protected virtual IWebElement EntityLink => EntityElement.FindElement(By.TagName("a"));
    public string EntityName => EntityLink.Text;

    public BaseAssociatedEntity(IWebElement entityElement, IWebDriver driver, string username, string password) 
        : base(driver, driver.Url, username, password, TimeoutInSecondsConstants.Three)
    {
        EntityElement = entityElement;
    }

    public bool Equals(BaseAssociatedEntity that)
    {
        return EntityName == that.EntityName;
    }
}

public class BaseAssociatedEntityEqual : EqualityComparer<BaseAssociatedEntity>
{
    public override bool Equals(BaseAssociatedEntity x, BaseAssociatedEntity y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (x is null || y is null) return false;

        return x.Equals(y);
    }

    public override int GetHashCode(BaseAssociatedEntity obj) => obj.GetHashCode();
}
  

Затем я хочу вызвать следующий метод, чтобы проверить, что 2 списка типа BaseAssociatedEntity являются SequenceEqual():

 protected bool BothNullOrEqual(List<BaseAssociatedEntity> left, List<BaseAssociatedEntity> right)
{
    if (left == null amp;amp; right == null) return true;
    if (left != null amp;amp; right != null) return left.SequenceEqual(right, new BaseAssociatedEntityEqual());
    return false;
}
  

Но в конечном итоге я пишу этот метод BothNullOrEqual для каждого отдельного объекта, который у меня есть:

 protected bool BothNullOrEqual(List<NotificationGroupAssociatedEntity> left,
    List<NotificationGroupAssociatedEntity> right)
{
    if (left == null amp;amp; right == null) return true;
    if (left != null amp;amp; right != null) return left.SequenceEqual(right, new NotificationGroupAssociatedEntityEqual());
    return false;
}
  

И так далее.. Как я могу сделать этот метод универсальным, чтобы он работал для всех типов, используя EqualityComparer, который я специально определил?

Ответ №1:

Просто сделайте метод универсальным как для типа данных, так и для типа средства сравнения:

 public static bool BothNullOrEqual<TData, TEqualityComparer>
    (IEnumerable<TData> left, IEnumerable<TData> right)
    where TEqualityComparer : IEqualityComparer<TData>, new()
{
    if (left is null amp;amp; right is null)
    {
        return true;
    }
    if (left is null || right is null)
    {
        return false;
    }
    return left.SequenceEqual(right, new TEqualityComparer());
}
  

Альтернативная версия с одним выражением:

 public static bool BothNullOrEqual<TData, TEqualityComparer>
    (IEnumerable<TData> left, IEnumerable<TData> right)
    where TEqualityComparer : IEqualityComparer<TData>, new() =>
    left is null
    ? right is null
    : right is object amp;amp; left.SequenceEqual(right, new TEqualityComparer());