I've read various questions similar to mine but none of them seem address my issue.
I've a type like this:
class MyObject<T> : IEquatable<MyObject<T>> { // no generic constraints
private readonly string otherProp;
private readonly T value;
public MyObject(string otherProp, T value)
{
this.otherProp = otherProp;
this.value = value;
}
public string OtherProp { get { return this.otherProp; } }
public T Value { get { return this.value; } }
// ...
public bool Equals(MyObject<T> other)
{
if (other == null)
{
return false;
}
return this.OtherProp.Equals(other.OtherProp) && this.Value.Equals(other.Value);
}
}
When T is a scalar as MyObject<int> equality works correctly, but when I defined something
like MyObject<IEnumerable<int>> equality fails.
The reason is that when T is IEnumerable<T> I should call this.Value.SequenceEqual(other.Value).
Handling this difference bloats Equals(MyObject<T>) with too LOC of type check and reflection (for me, leading to a violation of SOLID/SRP).
I was not able to found this specific case in MSDN guidelines, so if anyone already faced this problem; it would be great if this knowledge can be shared.
Edit: Alternative
To K.I.S.S., I'm wondering to doing something similar:
class MyObject<T> : IEquatable<MyObject<T>> {
private readonly IEnumerable<T> value;
// remainder omitted
}
In this way the implementation of Equal will be a lot simple. And when I need just one value I've a collection of 1 item.
Obviously T will not be an enumerable (but the data structure is private so there's no problem).
You could have your
MyObject<T>take an equality comparer for your typeTand use that:Then for
IEnumerable<T>you can use a comparer which compares the sequences instead of the references. You might want to make use of factory methods to create your objects to ensure the same comparer type is used for the sameTto ensure equality remains symmetric.