1

I have a List of Lists. To do some Opertations with each of those lists, i separate the Lists by a property and set a temp List with its value; The list can be sometimes empty. That is why i use this function for assignment.

EDIT: My current solution is this simple method. It should be easily adaptable.

   private List<string> setList(List<string> a, int count)
    {
        List < string > retr;
        if(a.Capacity == 0)
        {
            retr = new List<string>();
            for(int counter = 0; counter < count; counter++)
            {
              retr.Add(string.empty);
            }
        }
        else
        {
            retr = a;
        }
        return retr;
    }

Is there a better way to either take a list as values or initialize a list with element count? Or should I implement my own "List" class that has this behavior?

3
  • 4
    List.Capacity is not the same as List.Count, it doesn't get trimmed when you clear the list. What's the point of this method? Why wouldn't you instantiate a new list if the previous one is also empty? Also, there is no "list of lists" in your code. Commented Jul 26, 2016 at 8:26
  • I know that Capacity is not the same as count. I dont care in the initialization how many elements there are in the sub list, but how many there could be. Commented Jul 26, 2016 at 11:58
  • There is probably no objectively better way to do this highly unintuitive thing you're doing, other than removing the need for doing it in the first place. Even so, "is there a better way" kind of questions for working code are more material for Code Review. Commented Jul 26, 2016 at 12:10

2 Answers 2

2

You could use Enumerable.Repeat<T> if you wanted to avoid the loop:

var list = Enumerable.Repeat<string>("", count).ToList();

But there are several things that are problematic with your code:

  1. If Capacity is not 0, it doesn't mean it's equal to your desired count. Even if it is equal to the specified count, it doesn't mean that the actual List.Count is equal to count. A safer way would be to do:

    static List<string> PreallocateList(List<string> a, int count)
    {
        // reuse the existing list?
        if (a.Count >= count)
            return a;
    
        return Enumerable.Repeat("", count).ToList();
    }
    
  2. Preallocating a List<T> is unusual. It's usually common to use arrays when you have a fixed length known in advance.

    // this would (perhaps) make more sense
    var array = new string[count];
    
  3. And keep in mind, as mentioned in 1., that list's Capacity is not the same as Count:

    var list = new List<string>(10);
    
    // this will print 10
    Console.WriteLine("Capacity is {0}", list.Capacity);
    
    // but this will throw an exception           
    list[0] = "";
    

Most likely, however, this method is unnecessary and there is a better way to accomplish what you're doing. If nothing else, I would play the safe card and simply instantiate a new list each time (presuming that you have an algorithm which depends on a preallocated list):

static List<string> PreallocateList(int count)
{
    return Enumerable.Repeat("", count).ToList();
}

Or, if you are only interested in having the right capacity (not count), then just use the appropriate constructor:

static List<string> PreallocateList(int count)
{
    // this will prevent internal array resizing, if that's your concern
    return new List<string>(count);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, i know arrays are better for this job. Im trying to mess around with C# and its built in data models.
0

Your method is meaningless but equivalent to

static List<string> setList(List<string> a, int count) =>
    a.Capacity == 0 ? Enumerable.Repeat("", count).ToList() : a;

if you want Linq.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.