190 votes

Est-il préférable d'utiliser Enumerable<T>.Empty() plutôt que new List<T> pour initialiser un IEnumerable ?

Supposons que vous ayez une classe Personne :

public class Person
{
   public string Name { get; set;}
   public IEnumerable<Role> Roles {get; set;}
}

Je devrais évidemment instancier les rôles dans le constructeur. Maintenant, j'ai l'habitude de le faire avec une liste comme ceci :

public Person()
{
   Roles = new List<Role>();
}

Mais j'ai découvert cette méthode statique dans le System.Linq espace de noms

IEnumerable<T> Enumerable<T>.Empty<T>();

Desde MSDN :

La méthode Empty(TResult)() permet de mettre en cache une séquence vide de type TResult. Lorsque l'objet qu'elle retourne est énuméré elle ne renvoie aucun élément.

Dans certains cas, cette méthode est utile pour passer une séquence vide à une méthode définie par l'utilisateur qui prend un IEnumerable(T). Elle peut également être utilisée pour générer un élément neutre pour des méthodes telles que Union. Voir la section Exemple pour un exemple de cette utilisation de

Est-il préférable d'écrire le constructeur de cette manière ? L'utilisez-vous ? Pourquoi ? ou si non, pourquoi pas ?

public Person()
{
   Roles = Enumerable.Empty<Role>();
}

240voto

Vadim Chekan Points 728

Je pense que la plupart des messages ont manqué le point principal. Même si vous utilisez un tableau vide ou une liste vide, ce sont des objets et ils sont stockés en mémoire. Le Garbage Collector doit donc s'en occuper. Si vous avez affaire à une application à haut débit, l'impact peut être notable. Enumerable.Empty ne crée pas d'objet par appel, ce qui réduit la charge du GC.

Si le code se trouve dans un endroit où le débit est faible, on en revient à des considérations esthétiques.

117voto

Tommy Carlier Points 3954

Je pense que Enumerable.Empty est meilleur parce qu'il est plus explicite : votre code indique clairement vos intentions. Elle peut aussi être un peu plus efficace, mais ce n'est qu'un avantage secondaire.

13voto

Neil Barnwell Points 20731

Je pense que c'est tout à fait bien et lisible/maintenable d'être old-skool :

En supposant que vous souhaitiez vraiment remplir le formulaire Roles la propriété en quelque sorte :

public class Person
{
    public string Name { get; set; }
    public IList<Role> Roles { get; private set; }

    public Person()
    {
        Roles = new List<Role>();
    }
}

7voto

Lee Points 63849

Le problème avec votre approche est que vous ne pouvez pas ajouter d'éléments à la collection. J'aurais une structure privée comme list et j'exposerais les éléments comme un Enumerable :

public class Person
{
    private IList<Role> _roles;

    public Person()
    {
        this._roles = new List<Role>();
    }

    public string Name { get; set; }

    public void AddRole(Role role)
    {
        //implementation
    }

    public IEnumerable<Role> Roles
    {
        get { return this._roles.AsEnumerable(); }
    }
}

Si vous voulez qu'une autre classe crée la liste des rôles (ce que je ne recommande pas), je n'initialiserais pas du tout l'énumérable dans Person.

5voto

Henk Holterman Points 153608

Le plus gros problème ici serait d'exposer Roles en tant que champ public .

le suivant semble meilleur :

public class Person
{
   public string Name { get; set; }  

   private List<Role> _roles = null;
   public IEnumerable<Role> Roles 
   {
      get { 
        if (_roles != null) 
          return _roles;
        else
          return Enumerable.Empty<Role>();
        }
   }
}

Et peut-être que tu devrais regarder si tu peux le retourner comme un Collection à lecture seule selon l'utilisation que vous souhaitez en faire.

Et Enumerable.Empty n'est pas better ici, juste un peu plus efficace quand les rôles restent habituellement vides.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X