2012-07-27 12 views
7

Come nel titolo, qualcuno sa perché l'interfaccia ICollection non contiene un metodo Aggiungi? Sembra molto strano che la versione generica, ICollection<T>, abbia un Add ma non lo sia ICollection. Chiunque abbia una conoscenza più approfondita di questo sarebbe davvero d'aiuto.Perché ICollection non contiene un metodo Aggiungi?

Riguardo al motivo per cui mi interessa, sfortunatamente gli sviluppatori che hanno creato SharePoint non hanno mai imparato a conoscere i generici, quindi ogni singola raccolta nell'API è una raccolta non generica basata su ICollection. Mi piacerebbe collegare diversi metodi di estensione a ICollection che comportano l'aggiunta alla raccolta, tra le altre cose, ma questo sembra impossibile (almeno non possibile senza una riflessione).

EDIT:

poche persone sono speculando Il motivo è perché ICollection.Add richiederebbe un Object, e quindi non sarebbe typesafe. Questo non è il caso. IListha un metodo Add che accetta uno Object. Devi semplicemente eseguire un controllo tipografico e un cast in un metodo che richiede Object.

L'argomento che un array implementa ICollection e pertanto non può avere un Add inoltre non regge acqua. Se ICollection avesse un metodo Add, avrebbe solo bisogno di essere esplicitamente implementato sugli array e lanciare un'eccezione (come molti degli strumenti dei metodi che l'attrezzo fa attualmente).

Speravo davvero che qualcuno avesse un riferimento a una spiegazione di uno dei designer.

+0

lo fa? http://msdn.microsoft.com/en-us/library/63ywd54z.aspx –

+0

@MicahArmantrout, dice "ICollection ", ma "ICollection" no. –

+0

@MicahArmantrout È collegato alla versione generica. Ha già detto che la versione generica ce l'ha. Chiede perché il [non generico] (http://msdn.microsoft.com/en-us/library/system.collections.icollection (v = vs.100) .aspx) non lo fa. – vcsjones

risposta

0

Da MSDN

Non è necessario aggiungere i tipi di raccolta per i tipi conosciuti quando viene utilizzato polimorfico al posto di altre collezioni o interfacce di raccolta. Ad esempio, se si dichiara un membro dati di tipo IEnumerable e lo si utilizza per inviare un'istanza di ArrayList, non è necessario aggiungere ArrayList a tipi noti.

Quando si utilizzano le raccolte in modo polimorfico al posto dei tipi non di raccolta, devono essere aggiunti ai tipi noti. Ad esempio, se si dichiara un membro dati di tipo Object e lo si utilizza per inviare un'istanza di ArrayList, aggiungere ArrayList a tipi noti.

2

Per me sembra che la denominazione delle interfacce confonda le aspettative. ICollection e ICollection<T> non sono nemmeno nella stessa catena di ereditarietà - la maggior parte delle raccolte semplicemente implementa entrambe.

La documentazione che cosa l'interfaccia fa, in modo da prendere questo da solo, non ci si aspetterebbe Add di esistere:

dimensioni, enumeratori e metodi di sincronizzazione Definisce per tutti collezioni non generici.

Cosa ne penso? Personalmente penso che sia un vero e proprio gaffe di denominazione o la seconda volta (quando si introducono le interfacce generiche) i designer hanno scelto di inserire Add in ICollection<T> perché questa volta era più comune averne bisogno.

Il IList ha Add ed eredita ICollection che il IList<T> non ha Add e eredita ICollection<T>, che come Add.

Ricalcolare fino all'evoluzione/maturazione del tipo di progettazione gerarchia.


Per quanto riguarda i metodi di estensione, si può fare qualcosa di simile:

public static void AnotherMethod<T>(this ICollection<T> collection, T item) { } 

e utilizzarlo così:

ICollection<string> s; 
s.AnotherMethod(""); 
+0

'ICollection ' ... Mi piace, forse possiamo avere riferimenti musicali più decenti;) –

0

Sulla base di Msdn definition, è

dimensioni Definisce, enumeratori, e metodi di sincronizzazione per tutte le collezioni non generiche

Ciò significa ICollection rapresents un flusso o di una sequenza di dati che hai intenzione di leggere. Io direi che probabilmente la decisione che si trova dietro il SharePoint API è fornire flusso generico di dati da leggere dal server.

0

Un'ipotesi è che se il ICollection avesse il metodo Add, cosa impiegherebbe? Object ovviamente. Questo era un grosso problema con nessun array generico, che prima aveva C# 2.0.

Il problema è che è possibile aggiungere tipo diverso alla stessa collezione

+0

Questo non sarebbe davvero un problema. Dovresti semplicemente eseguire un controllo di tipo nel metodo ICollection.Add (oggetto) che genera se è il tipo sbagliato. – MgSam

+0

@MgSam, ma si sente ancora sbagliato avere un metodo che accetta un oggetto, quindi genera un'eccezione. – MBen

+0

MgSam: Ma come si definisce quale sia il tipo giusto se non è generico? E le eccezioni del runtime per cose come questa non mi sembrano divertenti. Poi di nuovo, provare a indovinare gli sviluppatori suona come non è divertente ... – Chris

1

ICollection può essere qualsiasi cosa. Potrebbe essere qualcosa che non è nient'altro che enumerabile. Non vi è alcun motivo per cui lo deve essere un metodo Add o un Remove. Se si guarda l'interfaccia più da vicino, è praticamente di sola lettura. Puoi vedere quanti elementi ci sono e puoi enumerarli. Questo è tutto. Questo ha perfettamente senso, in un modo astratto.

Quando arriviamo a ICollection<T>, ora siamo molto specifici. Sappiamo esattamente quale tipo di oggetto contiene e quindi possiamo:

  • Aggiungere nuovi elementi di <T>.
  • Cerca per loro utilizzando un tipo di interfaccia IEquitable.
  • Rimuovere loro, utilizzando la stessa metodologia.

In sostanza, la differenza è che ICollection<T> è un po 'concreto.

+1

Posso essere d'accordo con la tua opinione, ma penso che la ragione di fondo sia più legata all'evoluzione del design. 'IList' si aggiunge anche se non si conosce il tipo nella lista, tutti gli elenchi non generici hanno questo problema. La seconda volta con tutte le nuove interfacce per i generici, i progettisti possono avere la possibilità di unificare meglio le interfacce di base. O quello o è solo un gaff di denominazione. –

0

Wild guess - l'interfaccia ICollection è un'interfaccia di base per altre interfacce che la estendono, come IList e IDictionary. Queste interfacce hanno diverse implementazioni del metodo add. IList prende un param, IDictionary ne ha due ovviamente. Con i generici le firme del metodo di interfaccia derivata non sono molto diverse perché prendono un parametro - un tipo.

+0

ICollection non estende ICollection! – Anirudha

+0

Non l'ho mai detto. Stavo parlando dell'interfaccia System.Collections.ICollection, che è stata creata prima dei generici. – IanStallings

0

Quando ICollection è stato creato, non esistevano interfacce generiche. Ciò significava che se esisteva un metodo Add su ICollection, doveva avere la firma Add(object). ICollection intende dichiarare un'interfaccia coerente tra le raccolte di qualsiasi tipo, il che costringerebbe ciascuna raccolta ad agire, in parte, come una raccolta di object s.

Questo è stato risolto in ICollection<T> che ha un metodo Add(T).

0

Secondo Albahari Brothers

Le versioni generiche e non generici differiscono in modi al di là quello che si potrebbe aspettare, in particolare nel caso di ICollection.

Le ragioni di questo sono per lo più storico: perché i generici sono venuti tardi, le interfacce generiche sono state sviluppate con il beneficio del senno di poi .

Per questo motivo,

ICollection<T> non estende ICollection,

IList<T> non estende IList,

e IDictionary<TKey, TValue> non si estende IDictionary.

Per riassumere ICollection<T> si è evoluto da non commettere gli errori che sono stati fatti in ICollection .Questo è il motivo per cui ICollection<T> ha un metodo Add e non ICollection ..

Problemi correlati