2011-01-22 15 views
9

Eventuali duplicati:
count vs length vs size in a collectionPerché la matrice C# non ha una proprietà Count?

davvero strano:

C# array come il seguente

double[] test = new double[1]; 

supporta la proprietà lunghezza per ottenere la dimensione del array. Ma gli array implementano anche un'interfaccia IList:

IList<double> list = test; 

Tuttavia, l'interfaccia IList fornisce anche una proprietà Count. Come mai l'array ("test" in questo caso) no?

Edit: Grazie a tutti voi che ha sottolineato che in realtà è l'interfaccia ICollection (non IList), che fornisce la proprietà Count, e anche che questo è dovuto alla esplicita implementazione dell'interfaccia.

+2

... vs ** ** Capacità vs ** ** ItemCount (come 'ColumnCount' in' 'ListView' vs Columns.Count') vs ** ** NumItems (' NumIndices' in 'EnvDTE ') vs ** CountOfItems ** (' CountOfLines' in 'EnvDTE') vs etc ... Ho solo * amato * la coerenza nei framework di MS. :) – Mehrdad

risposta

14

Semplicemente, hanno scelto di chiamarla Length, e implementare Count tramite implementazione dell'interfaccia esplicita -Qualcosa piace:

int ICollection.Count { get { return Length; } } 
+2

+1 da parte mia, ma suppongo che forse stavano cercando una risposta alla parte "perché"? – Mehrdad

+1

@mehrdad - Vorrei avere la mia spec annotato su di me :( –

+1

Grazie per avermi alle implementazioni di interfaccia esplicite - non aveva idea che queste cose esistono ;-) – Chris

7

È stata una scelta di design su Naming, non semantica.

Gli array hanno una proprietà Lunghezza, così come la stringa.

Lunghezza segnali immutabili: non è possibile aggiungere o rimuovere da un array.

Elenchi e altri contenitori hanno una proprietà conteggio che di solito può cambiare.

Oh, e se chiami list.Append(1.1); otterrai un'eccezione non supportata.

+10

Lunghezza non significa segnali immutabili; 'MemoryStream' (in realtà, molte implementazioni stream),' StringBuilder', ecc. –

+0

@Marc: non intendevo implicare una regola molto rigida. Gli stream sono un altro dominio e penso che StringBuilder.Length sia una concessione a String. Continuo a pensare che valga vagamente per i contenitori. –

4

Tipi eredita da Arrayobtain implementations of IList<T> at run-time (come questo sia possibile, non chiedetemi):

In .NET Framework versione 2.0, la classe Array implementa il System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, e System.Collections.Generic.IEnumerable<T> interfacce generiche. Le implementazioni vengono fornite agli array in fase di esecuzione e pertanto non sono visibili agli strumenti di compilazione della documentazione . Come risultato, i generici interfacce non appaiono nella sintassi dichiarazione per la classe Array , e non ci sono riferimento argomenti di elementi di interfaccia che sono accessibili solo per fusione un array tipo interfaccia generica (esplicite implementazioni di interfaccia).La cosa importante per la chiave quando si esegue il cast di una matrice su una di queste interfacce è che i membri che aggiungono, inseriscono o rimuovono gli elementi restituiscono NotSupportedException.

In effetti l'attuazione IList<T> agisce come un explicit implementation, come Marc explained nella sua risposta. Questo è il motivo per cui è possibile accedere a certi membri della IList<T> dal risultato di un cast, ma non da una variabile di tipo T[] specificamente.

+0

L'ultima linea era in sostanza già nella domanda. –

+0

@Henk: hai ragione; Intendevo evidenziare la parte "implementazione esplicita"; incluso l'esempio di codice era superfluo e solo distratto da quel punto. L'ho rimosso. –

3

La proprietà Count è nascosto utilizzando l'interfaccia stile esplicita dichiarazione, ad esempio come questo in una definizione di classe:

int IList.Count { 
    get { 
     // ...etc... 
    } 
} 

È possibile accedere a metodi e proprietà nascoste come questo utilizzando un tipo di cast, per esempio

((IList<double>) myArray).Count 
+4

IList in realtà non definisce Count; ICollection fa –

+0

@Marc: il modo in cui le interfacce ereditano lo rende piuttosto discutibile. –

+0

@Henk - Avrei bisogno di controllare, ma lo * compila * se ti sbagli? Io non la penso così ... –

Problemi correlati