Qual è l'uso corretto dell'interfaccia IEnumerable in C # per gestire le raccolte?

2

Quando lavoro in ASP.Net MVC o WebApi, spesso mi trovo a creare viste o a restituire strutture di dati che includono "Elenco < >" di oggetti. Significa che ho una lista di oggetti dati che voglio restituire come parte di una vista.

So che la pratica migliore è che la proprietà per l'elenco dovrebbe essere un'interfaccia IEnumerable. Ma, così spesso sto creando questi elenchi nel momento in cui creo il modello di visualizzazione.

Quindi, dove va bene inizializzare la lista < & gt ;? È meglio farlo in un costruttore per la vista, o meglio farlo nel metodo di chiamata?

Codice per revisione:

    public class AllProfilesViewModel
{
    public AllProfilesViewModel(IEnumerable<FullUserProfile> allProfiles)
    {
        AllProfiles = allProfiles;
    }

    public AllProfilesViewModel()
    {
        AllProfiles = new List<FullUserProfile>();
    }

    public IEnumerable<FullUserProfile> AllProfiles { get; set; }        
}

public struct FullUserProfile
{
    public string Id { get; set; }
    public bool IsActive { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
    
posta Paul Duer 19.09.2018 - 15:08
fonte

2 risposte

7

Personalmente farei qualcosa di simile

public class AllProfilesViewModel
{
    public AllProfilesViewModel(IEnumerable<FullUserProfile> allProfiles)
    {
        _allProfilesList.AddRange(allProfiles);
    }

    private List<FullUserProfile> _allProfilesList = new List<FullUserProfile>();

    public IReadOnlyCollection<FullUserProfile> AllProfiles 
    { get {return _allProfilesList.AsReadOnly(); } }

    public void AddProfile(FullUserProfile profile)
    { _allProfilesList.Add(profile); } 
}

Mantieni ViewModel come una scatola nera: gli utenti di questa classe non hanno bisogno di conoscere l'effettiva implementazione della lista.

La creazione della proprietà AllProfiles come ReadOnlyCollection rende chiaro al chiamante in che modo è possibile utilizzare il set di elementi di dati: è una dimensione finita, include una proprietà count, può essere ripetuta più volte senza alcun impatto sulle prestazioni, ma non può essere aggiornato.

    
risposta data 19.09.2018 - 15:24
fonte
5

Primo:

I know that best practice is that the property for the List should be a IEnumerable interface.

Non necessariamente. IEnumerable è un'interfaccia di raccolta di sola lettura, ad accesso sequenziale. Ci sono molti casi in cui questo è esattamente ciò di cui hai bisogno, ma molti altri casi in cui non lo sono. A seconda del tuo caso d'uso, ICollection , IReadOnlyList o varie altre interfacce potrebbero essere appropriate. Se vuoi che il consumatore sia in grado di aggiungere cose, è probabilmente meglio semplicemente rendere la proprietà a List e mantenerla semplice. Ulteriori livelli di riferimento indiretto hanno costi, non solo in termini di prestazioni, ma anche di leggibilità e manutenibilità del codice.

Detto questo:

So where is it okay to initialize the List<>? Is it best to do it in a constructor for the View, or best to do it in the calling method?

Anche se il consumatore non dovrebbe cambiare il contenuto della raccolta, è probabile che la tua classe vorrà farlo ad un certo punto. In questo esempio, abbiamo un elenco di tutti i profili utente. Quando un nuovo utente si registra, vogliamo aggiungere a quell'elenco. Quindi probabilmente il modo migliore per farlo è avere un campo privato di tipo List<FullUserProfile> , che viene creato nel costruttore, (o semplicemente inizializzato nella sua dichiarazione,) e quindi una proprietà pubblica di tipo IEnumerable<FullUserProfile> (o qualsiasi raccolta interfaccia è appropriata) il cui get restituisce la lista.

    
risposta data 19.09.2018 - 15:25
fonte

Leggi altre domande sui tag