2012-04-11 7 views

risposta

324

Generalmente ciò che si sceglie dipende dai metodi a cui è necessario accedere. In generale - IEnumerable<> (MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx) per un elenco di oggetti che devono essere semplicemente iterati, ICollection<> (MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx) per un elenco di oggetti che devono essere iterati e modificati, List<> per un elenco di oggetti che richiede per essere iterato, modificato, ordinato, ecc. (Vedi qui per un elenco completo: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).

Da un punto di vista più specifico, il caricamento lento entra in gioco con la scelta del tipo. Per impostazione predefinita, le proprietà di navigazione in Entity Framework includono il rilevamento delle modifiche e sono proxy. Per poter creare il proxy dinamico come proprietà di navigazione, il tipo virtuale deve implementare ICollection.

Una proprietà di navigazione che rappresenta la "molti" fine di una relazione deve restituire un tipo che implementa ICollection, dove T è il tipo di oggetto all'altra estremità della relazione. - Requirements for Creating POCO ProxiesMSDN

More information on Defining and Managing RelationshipsMSDN

+0

quindi, con quello, 'List' dovrebbe essere molto meglio, sì? –

+2

@JanCarloViray - Tendo ad usare 'List' molto. Sebbene abbia il maggior overhead, fornisce la maggior parte delle funzionalità. –

+1

Gli elenchi sono definiti più dai loro indicizzatori che dalla possibilità di ordinarli (avere un indicizzatore intero rende facile ordinare qualcosa, ma non è un requisito). – phoog

63

ICollection<T> viene utilizzato perché l'interfaccia IEnumerable<T> non consente di aggiungere elementi, rimuovere elementi o modificare in altro modo la raccolta.

+1

per quanto riguarda il confronto contro Lista ? –

+9

'Elenco ' implementa 'ICollection '. – spender

+0

L''ICollection' non generico non consente alcun modo di aggiungere elementi, ma è comunque un utile complemento a' IEnumerable 'perché fornisce un membro' Count' che è in genere molto più veloce dell'enumerazione di tutto. Si noti che se un 'IList ' o 'ICollection ' viene passato al codice che si aspetta un 'IEnumerable ', il metodo di estensione 'Count()' sarà veloce se implementa il 'ICollection' non generico, ma non se esso implementa solo le interfacce generiche poiché un tipico 'ICollection ' non implementa 'ICollection '. – supercat

8

L'idea di base dell'utilizzo di ICollection è fornire un'interfaccia per l'accesso di sola lettura a una quantità limitata di dati. In effetti hai una proprietà ICollection.Count. IEnumerable è più adatto per alcune catene di dati in cui si legge fino a un certo punto logico, alcune condizioni specificate esplicitamente dal consumatore o fino alla fine dell'enumerazione.

+13

TIL that ['ICollection'] (http://msdn.microsoft.com/en-us/library/System.Collections.ICollection%28v=vs.110%29.aspx) è di sola lettura mentre ['ICollection '] (http://msdn.microsoft.com/en-us/library/c28hx0c4%28v=vs.110%29.aspx) non lo è. –

39

Rispondendo alla tua domanda su List<T>:

List<T> è una classe; specificare un'interfaccia consente una maggiore flessibilità di implementazione. Una domanda migliore è "perché non IList<T>?"

Per rispondere a questa domanda, considerare cosa aggiunge IList<T> allo ICollection<T>: indicizzazione di numeri interi, ovvero gli articoli hanno un ordine arbitrario e possono essere recuperati in base a tale ordine. Questo probabilmente non è significativo nella maggior parte dei casi, dal momento che gli articoli probabilmente devono essere ordinati diversamente in contesti diversi.

+3

+1 Buon punto su IList –

1

Quello che ho fatto in passato è dichiarare le mie collezioni classe interna utilizzando IList<Class>, ICollection<Class> o IEnumerable<Class> (se statico lista) a seconda se o non dovrò fare un numero qualsiasi di quanto segue in un metodo in mio repository: enumerare, ordinare/modificare o modificare. Quando ho solo bisogno di enumerare (e magari ordinare) su oggetti, creo una temp List<Class> per lavorare con la collezione all'interno di un metodo IEnumerable.Penso che questa pratica sarebbe efficace solo se la collezione è relativamente piccola, ma potrebbe essere una buona pratica in generale, idk. Per favore correggimi se ci sono prove sul perché questa non sarebbe una buona pratica.

3

Mi ricordo in questo modo:

  1. IEnumerable ha un metodo GetEnumerator(), che permette di leggere i valori in una collezione, ma non scrivere. La maggior parte della complessità dell'utilizzo dell'enumeratore è gestita da noi per ogni istruzione in C#. IEnumerable ha una proprietà: Current, che restituisce l'elemento corrente.

  2. ICollection implementa IEnumerable e aggiunge alcune proprietà aggiuntive il cui utilizzo maggiore è Count. La versione generica di ICollection implementa i metodi Add() e Remove().

  3. IList implementa sia IEnumerable che ICollection.

+1

Sulla base di ciò che hai scritto ICollection e IList sono gli stessi. Si prega di aggiungere ciò che viene aggiunto a IList che non esiste in ICollection. – bets

5

ci sono alcune differenze fondamentali tra l'ICollection e IEnumerable

  • IEnumeration - Contiene unico metodo GetEnumerator per ottenere Enumerator e fare un loop
  • ICollection è che contiene la seguenti metodi - Aggiungi/Rimuovi/Contiene/Conteggio/Copia
  • ICollection è ereditato da IEnumerable
  • Con ICollection è possibile modificare la collezione utilizzando i metodi come aggiungere/rimuovere, non avete la libertà di fare lo stesso con IEnumerable.

semplice programma: proprietà

using System; 
using System.Collections; 
using System.Collections.Generic; 

namespace StackDemo 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Person> persons = new List<Person>(); 
      persons.Add(new Person("John",30)); 
      persons.Add(new Person("Jack", 27)); 

      ICollection<Person> personCollection = persons; 
      IEnumerable<Person> personEnumeration = persons; 

      //IEnumeration 
      //IEnumration Contains only GetEnumerator method to get Enumerator and make a looping 
      foreach (Person p in personEnumeration) 
      {         
       Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age); 
      } 

      //ICollection 
      //ICollection Add/Remove/Contains/Count/CopyTo 
      //ICollection is inherited from IEnumerable 
      personCollection.Add(new Person("Tim", 10)); 

      foreach (Person p in personCollection) 
      { 
       Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);   
      } 
      Console.ReadLine(); 

     } 
    } 

    class Person 
    { 
     public string Name { get; set; } 
     public int Age { get; set; } 
     public Person(string name,int age) 
     { 
      this.Name = name; 
      this.Age = age; 
     } 
    } 
} 
2

di navigazione sono tipicamente definito come virtuale in modo che possano usufruire di alcune funzionalità Entity Framework come pigri carico.

Se una proprietà di navigazione può contenere più entità (come nelle relazioni molti a molti o uno-a-molti), il suo tipo deve essere un elenco in cui le voci possono essere aggiunte, eliminate e aggiornate, come ad esempio ICollection .

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application

Problemi correlati