Подтвердить что ты не робот

Как инициализировать список с помощью конструктора?

У меня есть тип:

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;
    }        
}

Прошу вас посоветовать в числе лучших практик использования конструктора для инициализации списка? Как инициализировать список с помощью конструктора?

Edit:

Прошу вас посоветовать в числе лучших практик использования конструктора для инициализации списка? Как назначить значения для списка с помощью конструктора, поэтому, если значение, принятое по умолчанию, будет использоваться?

Спасибо

4b9b3361

Ответ 1

Использование инициализатора коллекции

Из С# 3 вы можете использовать инициализаторы коллекции для создания списка и заполнения его одним выражением. В следующем примере строятся объекты Human и ContactNumbers:

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

Специализация конструктора Human

Вы можете изменить конструктор класса Human, чтобы обеспечить способ заполнения свойства 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)
);

Нижняя строка

Какая альтернатива - лучшая практика? Или, по крайней мере, хорошая практика? Вы это судите! ИМО, лучшая практика заключается в том, чтобы написать программу как можно яснее всем, кто должен ее прочитать. Использование инициализатора коллекции является для меня победителем, в данном случае. С гораздо меньшим количеством кода он может делать почти то же самое, что и альтернативы - по крайней мере, альтернативы, которые я дал...

Ответ 2

Вы ищете это?

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

Ответ 3

ContactNumbers = new List<ContactNumber>();

Если вы хотите, чтобы он был передан, просто возьмите

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

Ответ 4

Вы можете инициализировать его точно так же, как и любой список:

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
}       

Однако я бы даже сделал еще один шаг и сделал setter частным, так как вам часто не нужно устанавливать список, а просто получать доступ/изменять его содержимое:

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

Ответ 5

В общем случае не публиковать List<T> публично и не предоставлять сеттеры для свойств коллекции. Кроме того, вы можете скопировать элементы переданного списка (как показано ниже). В противном случае изменения в исходном списке будут влиять на экземпляр Human.

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>();
}

Другой вариант - использовать конструктор списка, который принимает коллекцию и удаляет инициализатор поля.