C# 如何使用构造函数初始化列表?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9088585/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:51:04  来源:igfitidea点击:

How to initialize a list with constructor?

c#.netvisual-studioasp.net-3.5

提问by haansi

I have a 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;
    }        
}

Please guide me is among best practices to use constructor with for list initialization? How to initialize a list using constructor?

请指导我是使用构造函数进行列表初始化的最佳实践之一吗?如何使用构造函数初始化列表?

Edit:

编辑:

Please guide me is among best practices to use constructor with for list initialization? How to assign values to list using a constructor, so if no value passed a default will be used?

请指导我是使用构造函数进行列表初始化的最佳实践之一吗? 如何使用构造函数为列表赋值,所以如果没有传递值,将使用默认值?

Thanks

谢谢

采纳答案by Humberto

Using a collection initializer

使用集合初始值设定项

From C# 3, you can use collection initializers to construct a List and populate it using a single expression. The following example constructs a Human and its ContactNumbers:

从 C# 3 开始,您可以使用集合初始值设定项来构造 List 并使用单个表达式填充它。以下示例构造了一个 Human 及其 ContactNumbers:

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

Specializing the Humanconstructor

专门的Human构造函数

You can change the constructor of the Humanclass to provide a way to populate the ContactNumbersproperty:

您可以更改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)
);

Bottom line

底线

Which alternative is a best practice? Or at least a good practice? You judge it! IMO, the best practice is to write the program as clearly as possible to anyone who has to read it. Using the collection initializer is a winner for me, in this case. With much less code, it can do almost the same things as the alternatives -- at least, the alternatives I gave...

哪个替代方案是最佳实践?或者至少是一个好的做法?你判断吧!IMO,最佳做法是将程序尽可能清楚地编写给必须阅读它的任何人。在这种情况下,使用集合初始值设定项对我来说是赢家。用更少的代码,它可以做与替代品几乎相同的事情——至少,我给出的替代品......

回答by eouw0o83hf

ContactNumbers = new List<ContactNumber>();

If you want it to be passed in, just take

如果你想把它传进去,就拿

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

回答by Kiril

You can initialize it just like any list:

您可以像任何列表一样初始化它:

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
}       

However, I would even go a step further and make the setter private since you often don't need to set the list, but just access/modify its contents:

但是,我什至会更进一步,将 setter 设为私有,因为您通常不需要设置列表,而只需访问/修改其内容:

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

回答by TrueWill

In general don't expose List<T>publicly, and don't provide setters for collection properties. Also, you may want to copy the elements of the passed list (as shown below). Otherwise changes to the original list will affect the Human instance.

一般不List<T>公开,也不提供集合属性的setter。此外,您可能希望复制传递列表的元素(如下所示)。否则对原始列表的更改将影响 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>();
}

Another option is to use the list constructor that takes a collection and remove the field initializer.

另一种选择是使用接受集合并删除字段初始值设定项的列表构造函数。

回答by joce

Are you looking for this?

你在找这个吗?

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