2012-01-31 2 views
27

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

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:

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

Благодаря

ответ

46

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

От C# 3, вы можете использовать коллекцию инициализаторами для построения списка и заполнить его с помощью одного выражения. Следующий пример создает человек и его 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) 
); 

Итог

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

+0

спасибо Humberto, plz see my edit – haansi

3
ContactNumbers = new List<ContactNumber>(); 

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

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

Спасибо @ eouw0o83hf, Я извиняюсь за мои не достаточно объяснений. Я хочу передать номера для списка с помощью конструктора. Не стесняйтесь также сказать, что это хороший способ передать значения для списка, как мы передаем другие значения? – haansi

+0

Вы ищете ключевое слово [params] (http://msdn.microsoft.com/en-us/library/w5zay9db.aspx)? – TrueWill

+0

Нет TrueWill, я хочу назначить значения для списка с помощью конструктора. Пожалуйста, также объясните, как обращаться, если никакие значения не назначаются (что было бы по умолчанию)? Это стандартный способ? – haansi

2

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

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 
}  

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

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

Спасибо @Lirik, любезно посоветуйте, как передать значения в список из constrcot? также руководство - это стандартный способ использования constroctor для передачи значений в свойство, которое является списком в основном? – haansi

1

В общем, не подвергать 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>(); 
} 

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

+0

Спасибо @TrueWill, не можем ли мы заполнить список и передать его конструктору так же, как мы передаем другие значения через конструктор, а если нет значений, то присвойте значение по умолчанию? как это будет сделано? Это хороший способ сделать это? – haansi

+1

Всё зависит. Вы передаете ** ссылку **. Вы хотите, чтобы контакты человека менялись при изменении исходного списка контактов? Если вам нужен список по умолчанию, я бы обычно добавлял конструктор по умолчанию для человека, который создавал бы пустой список. Избегайте пустых ссылок, когда это возможно. Также избегайте пустых списков специальных корпусов. – TrueWill

5

Вы ищете это?

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

спасибо Joce, см. Мое редактирование. – haansi