Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implement IEquatable<T> when T could be IEnumerable<T>

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).

like image 354
jay Avatar asked Mar 19 '13 08:03

jay


1 Answers

In case when T is IEnumerable<T>, your code compares two references of IEnumerable<T> and, of course, those references may be not equal. Actually, you'll get this behavior, when T will be any reference type without overridden Equals method.

If you don't want to compare references here, you should write a code, which will compare these sequences by their content. However, you should note, that sequence may be endless.

like image 78
Dennis Avatar answered Sep 29 '22 04:09

Dennis