Ho letto varie domande simili alle mie ma nessuna di esse sembra risolvere il mio problema.Implement IEable <T> quando T potrebbe essere IEnumerable <T>
ho un tipo come questo:
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);
}
}
Quando T
è uno scalare come MyObject<int>
uguaglianza funziona correttamente, ma quando ho definito qualcosa di simile MyObject<IEnumerable<int>>
uguaglianza non riesce.
Il motivo è che quando T è IEnumerable<T>
dovrei chiamare this.Value.SequenceEqual(other.Value)
.
Gestione di questa differenza a gonfie dimensioni Equals(MyObject<T>)
con troppo LOC di tipo check e reflection (per me, che porta a una violazione di SOLID/SRP).
Non sono stato in grado di trovare questo caso specifico nelle linee guida MSDN, quindi se qualcuno ha già affrontato questo problema; sarebbe bello se questa conoscenza potesse essere condivisa.
Edit: Alternative
Per K.I.S.S., mi chiedo a fare qualcosa di simile:
class MyObject<T> : IEquatable<MyObject<T>> {
private readonly IEnumerable<T> value;
// remainder omitted
}
In questo modo l'implementazione di Equal
sarà molto semplice. E quando ho bisogno di un solo valore, ho una collezione di 1 oggetto. Ovviamente T non sarà un enumerabile (ma la struttura dati è privata quindi non ci sono problemi).
Se è possibile nel tuo caso, puoi anche aggiungere un vincolo generico 'dove T: IEquatable'. –
Guillaume
@Guillaume, devo valutare e ragionare su di esso ... – jay
Per riferimento, voglio aggiungere quello che va nella risposta sotto __Edit: Alternative__ era vicino alla mia vera soluzione. Sto sperimentando che non c'è motivo valido per non usare un 'IEnumerable' anche quando nella maggior parte dei casi la raccolta di 'T' manterrà solo un elemento o piuttosto sarà vuota. Questo non è il caso, la collezione spesso contiene da uno a pochi elementi; quindi direi che 'IEnumerable ' dovrebbe essere _hard coded_ nella definizione di 'MyObject ' piuttosto che facoltativamente passato nel suo insieme attraverso il parametro type (sto parlando di evitare 'MyObject >' e vai per l'alternativa). –
jay