How to initialize a List to a given size (as opposed to capacity)?

前端 未结 15 2165
礼貌的吻别
礼貌的吻别 2020-11-28 06:41

.NET offers a generic list container whose performance is almost identical (see Performance of Arrays vs. Lists question). However they are quite different in initialization

相关标签:
15条回答
  • 2020-11-28 06:43

    You seem to be emphasizing the need for a positional association with your data, so wouldn't an associative array be more fitting?

    Dictionary<int, string> foo = new Dictionary<int, string>();
    foo[2] = "string";
    
    0 讨论(0)
  • 2020-11-28 06:44

    The accepted answer (the one with the green check mark) has an issue.

    The problem:

    var result = Lists.Repeated(new MyType(), sizeOfList);
    // each item in the list references the same MyType() object
    // if you edit item 1 in the list, you are also editing item 2 in the list
    

    I recommend changing the line above to perform a copy of the object. There are many different articles about that:

    • String.MemberwiseClone() method called through reflection doesn't work, why?
    • https://code.msdn.microsoft.com/windowsdesktop/CSDeepCloneObject-8a53311e

    If you want to initialize every item in your list with the default constructor, rather than NULL, then add the following method:

    public static List<T> RepeatedDefaultInstance<T>(int count)
        {
            List<T> ret = new List<T>(count);
            for (var i = 0; i < count; i++)
            {
                ret.Add((T)Activator.CreateInstance(typeof(T)));
            }
            return ret;
        }
    
    0 讨论(0)
  • 2020-11-28 06:44

    This is a sample I used for my unit test. I created a list of class object. Then I used forloop to add 'X' number of objects that I am expecting from the service. This way you can add/initialize a List for any given size.

    public void TestMethod1()
        {
            var expected = new List<DotaViewer.Interface.DotaHero>();
            for (int i = 0; i < 22; i++)//You add empty initialization here
            {
                var temp = new DotaViewer.Interface.DotaHero();
                expected.Add(temp);
            }
            var nw = new DotaHeroCsvService();
            var items = nw.GetHero();
    
            CollectionAssert.AreEqual(expected,items);
    
    
        }
    

    Hope I was of help to you guys.

    0 讨论(0)
  • 2020-11-28 06:46

    You can use Linq to cleverly initialize your list with a default value. (Similar to David B's answer.)

    var defaultStrings = (new int[10]).Select(x => "my value").ToList();
    

    Go one step farther and initialize each string with distinct values "string 1", "string 2", "string 3", etc:

    int x = 1;
    var numberedStrings = (new int[10]).Select(x => "string " + x++).ToList();
    
    0 讨论(0)
  • 2020-11-28 06:47

    Use the constructor which takes an int ("capacity") as an argument:

    List<string> = new List<string>(10);
    

    EDIT: I should add that I agree with Frederik. You are using the List in a way that goes against the entire reasoning behind using it in the first place.

    EDIT2:

    EDIT 2: What I'm currently writing is a base class offering default functionality as part of a bigger framework. In the default functionality I offer, the size of the List is known in advanced and therefore I could have used an array. However, I want to offer any base class the chance to dynamically extend it and therefore I opt for a list.

    Why would anyone need to know the size of a List with all null values? If there are no real values in the list, I would expect the length to be 0. Anyhow, the fact that this is cludgy demonstrates that it is going against the intended use of the class.

    0 讨论(0)
  • 2020-11-28 06:49

    If you want to initialize the list with N elements of some fixed value:

    public List<T> InitList<T>(int count, T initValue)
    {
      return Enumerable.Repeat(initValue, count).ToList();
    }
    
    0 讨论(0)
提交回复
热议问题