web-dev-qa-db-fra.com

Comment initialiser une liste avec constructeur?

J'ai un type:

public  class Human
{
    public int Id { get; set; }
    public string Address { get; set; }
    public string Name { get; set; }
    public List<ContactNumber> ContactNumbers { get; set; }

    public Human(int id)
    {
        Id = id;
    }

    public Human(int id, string address, string name,
                 List<ContactNumber> contactNumbers) :
        this(id)
    {
        Address = address;
        Name = name;
        ContactNumbers = contactNumbers;
    }        
}

Veuillez me guider est parmi les meilleures pratiques à utiliser avec le constructeur pour l'initialisation de la liste? Comment initialiser une liste à l'aide du constructeur?

Modifier:

Veuillez me guider est parmi les meilleures pratiques à utiliser avec le constructeur pour l'initialisation de la liste? Comment attribuer des valeurs à la liste à l'aide d'un constructeur, donc si aucune valeur n'est passée, une valeur par défaut sera utilisée?

Merci

30
haansi

tilisation d'un initialiseur de collection

À partir de C # 3, vous pouvez utiliser des initialiseurs de collection pour construire une liste et la remplir à l'aide d'une seule expression. L'exemple suivant construit un humain et ses numéros de contact:

var human = new Human(1, "Address", "Name") {
    ContactNumbers = new List<ContactNumber>() {
        new ContactNumber(1),
        new ContactNumber(2),
        new ContactNumber(3)
    }
}

Spécialisation du constructeur Human

Vous pouvez changer le constructeur de la classe Human pour fournir un moyen de remplir la propriété ContactNumbers:

public class Human
{
    public Human(int id, string address, string name, IEnumerable<ContactNumber> contactNumbers) : this(id, address, name)
    {
        ContactNumbers = new List<ContactNumber>(contactNumbers);
    }

    public Human(int id, string address, string name, params ContactNumber[] contactNumbers) : this(id, address, name)
    {
        ContactNumbers = new List<ContactNumber>(contactNumbers);
    }
}

// Using the first constructor:
List<ContactNumber> numbers = List<ContactNumber>() {
    new ContactNumber(1),
    new ContactNumber(2),
    new ContactNumber(3)
};

var human = new Human(1, "Address", "Name", numbers);

// Using the second constructor:
var human = new Human(1, "Address", "Name",
    new ContactNumber(1),
    new ContactNumber(2),
    new ContactNumber(3)
);

Conclusion

Quelle alternative est une meilleure pratique? Ou au moins une bonne pratique? Vous le jugez! OMI, la meilleure pratique est d'écrire le programme aussi clairement que possible à toute personne qui doit le lire. L'utilisation de l'initialiseur de collection est un gagnant pour moi, dans ce cas. Avec beaucoup moins de code, il peut faire presque les mêmes choses que les alternatives - au moins, les alternatives que j'ai données ...

57
Humberto

Vous cherchez cela?

ContactNumbers = new List<ContactNumber>(){ new ContactNumber("555-5555"),
                                            new ContactNumber("555-1234"),
                                            new ContactNumber("555-5678") };
5
joce
ContactNumbers = new List<ContactNumber>();

Si vous voulez qu'il soit transmis, prenez simplement

public Human(List<ContactNumber> numbers)
{
 ContactNumbers = numbers;
}
3
eouw0o83hf

Vous pouvez l'initialiser comme n'importe quelle liste:

public List<ContactNumber> ContactNumbers { get; set; }

public Human(int id)
{
    Id = id;
    ContactNumbers = new List<ContactNumber>();
}

public Human(int id, string address, string name) :this(id)
{
    Address = address;
    Name = name;
    // no need to initialize the list here since you're
    // already calling the single parameter constructor
}       

Cependant, j'irais même plus loin et rendrais le setter privé car vous n'avez souvent pas besoin de définir la liste, mais simplement d'accéder/modifier son contenu:

public List<ContactNumber> ContactNumbers { get; private set; }
2
Kiril

En général, n'exposez pas List<T> publiquement et ne fournit pas de setters pour les propriétés de collection. Vous pouvez également vouloir copier les éléments de la liste transmise (comme indiqué ci-dessous). Sinon, les modifications apportées à la liste d'origine affecteront l'instance humaine.

public class Human
{
    public Human()
    {
    }

    public Human(IEnumerable<ContactNumber> contactNumbers)
    {
        if (contactNumbers == null)
        {
            throw new ArgumentNullException("contactNumbers");
        }

        _contactNumbers.AddRange(contactNumbers);
    }

    public IEnumerable<ContactNumber> ContactNumbers
    {
        get { return _contactNumbers; }
    }

    private readonly List<ContactNumber> _contactNumbers = new List<ContactNumber>();
}

Une autre option consiste à utiliser le constructeur de liste qui prend une collection et à supprimer l'initialiseur de champ.

1
TrueWill