从现有集合

时间:2018-04-25 08:09:30

标签: c#

我有一个带有get-only集合属性的类。我想用现有集合中的值初始化集合。

我知道可以初始化集合using a collection initializer。我也可以创建对象,然后在集合上使用AddRange来添加现有集合的项目。但是,这将创建具有空列表的对象,然后添加现有项。

有没有办法在首先正确初始化List的情况下创建对象(当然不添加构造函数)?

using System.Collections.Generic;

namespace EmptyConsoleApp
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            // Compiles, but is not what I need
            var firstHolder = new Holder()
            {
                TheList = {"A", "B"}
            };

            // Compiles, but initializes the list after object creation
            var existingList = new List<string>() {"Foo", "Bar"};
            var secondHolder = new Holder();
            secondHolder.TheList.AddRange(existingList);

            // Does not compile
            var thirdHolder = new Holder()
            {
                TheList = {existingList}
            };
        }
    }

    internal class Holder
    {
        public Holder()
        {
            TheList = new List<string>();
        }

        public List<string> TheList { get; }
    }
}

3 个答案:

答案 0 :(得分:1)

没有。您无法从集合初始值设定项中分配此只读属性。毕竟它是只读的。

TheList = { "A", "B" }有效,因为它在Add上调用了TheList(每个项目添加一次),它不会创建并分配一个新实例,但不允许这样做

由于存在输入问题(TheList = { existingList }确实有效),

TheList = { existingList[0] }无法正常工作。

你有最好的选择来创建一个构造函数参数,并放弃使用集合初始值设定项来解决它不适合的事情。

答案 1 :(得分:0)

  

有没有办法在首先正确初始化List的情况下创建对象(当然不添加构造函数)?

没有

不是。这就是构造函数的作用。如果您不想在构造函数中执行此操作,则无法执行此操作。

答案 2 :(得分:0)

无法从类本身外部初始化只读属性。

集合初始化程序只是一个简化的语法版本,它并不意味着使用此语法,您具有与在类构造函数中相同的访问权限

 thirdHolder.TheList = existingList; // this is the traditional way

也许您可以像这样使用工厂类模式

   internal class Program
{
    public static void Main(string[] args)
    {
        // Compiles, but is not what I need
        var firstHolder = new Holder()
        {
            TheList = { "A", "B" }
        };

        // Compiles, but initializes the list after object creation
        var existingList = new List<string>() { "Foo", "Bar" };
        var secondHolder = new Holder();
        secondHolder.TheList.AddRange(existingList);

        // Does not compile
        //var thirdHolder = new Holder()
        //{
        //    TheList =  existingList 
        //};

        //thirdHolder.TheList = existingList; // this is the traditional way
        var thirdHolder = Holder.HolderFactory(existingList);
    }
}


internal class Holder
{
    public Holder()
    {
        TheList = new List<string>();
    }

    public static Holder HolderFactory(List<string> theList)
    {
        return new Holder(theList);
    }
    private Holder(List<string> theList)
    {
        this.TheList = theList;
    }
    public List<string> TheList { get; }
}