I have many objects in which I want to check that lists of those objects are equal.
For each object I have defined an 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();
}
I then want to call the following method to check that 2 lists of type BaseAssociatedEntity are 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;
}
But I end up writing this BothNullOrEqual method for every single object that I have:
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;
}
And so on.. How can I make this method generic so that it works for all types, using the EqualityComparer that I have specifically defined?
Just make the method generic in both the data type and the comparer type:
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());
}
An alternative single expression version:
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 && left.SequenceEqual(right, new TEqualityComparer());