创建一个通用方法来使用我为特定类型定义的EqualityComparer

问题描述

我有很多对象要检查这些对象的列表是否相等。

我为每个对象定义了一个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 && right == null) return true;
    if (left != null && right != null) return left.SequenceEqual(right,new BaseAssociatedEntityEqual());
    return false;
}

但是我最终为我拥有的每个对象写了BothNullOrEqual方法

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

等等。如何使用我专门定义的EqualityComparer,使该方法通用,使其适用于所有类型?

解决方法

只需使该方法在数据类型和比较器类型中通用:

public static bool BothNullOrEqual<TData,TEqualityComparer>
    (IEnumerable<TData> left,IEnumerable<TData> right)
    where TEqualityComparer : IEqualityComparer<TData>,new()
{
    if (left is null && 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,new() =>
    left is null
    ? right is null
    : right is object && left.SequenceEqual(right,new TEqualityComparer());