Initialize List<T> with index--is this a bug?

91 Views Asked by At

In C# you can initialize Dictionary<TKey,TValue> like this:

var dictionary = new Dictionary<int, string>()
{
  [0] = "Hello",
  [1] = "World"
};

You can also initialize List<T> like this:

var listA = new List<string>()
{
  "Hello",
  "World"
};

The two examples listed above compile and run with no exceptions.

However, the following example compiles, but throws an exception:

var listB = new List<string>()
{
  [0] = "Hello",
  [1] = "World"
};
// System.ArgumentOutOfRangeException: Index was out of range.
// Must be non-negative and less than the size of the collection.
// (Parameter 'index') at System.Collections.Generic.List`1.set_Item(Int32 index, T value)

Is this an unfinished feature, since it compiles but throws an exception? If not, shouldn't this be a compilation error?

I'm using C# 12 and ASP.NET 8

2

There are 2 best solutions below

2
gunr2171 On
var listB = new List<string>()
{
  [0] = "Hello",
  [1] = "World"
};

is compiled to:

List<string> list = new List<string>();
list[0] = "Hello";
list[1] = "World";

From the Docs:

The preceding sample generates code that calls the Item[TKey] to set the values.

Of course, the exception makes sense because when you initialize the list, it has zero elements. Elements at index 0 and 1 don't exist.

3
Tim Schmelter On

To complete gunr2171's answer, the first example with the dictionary does not use the indexer as in the 2nd example with the list(which tries to assign strings to list-indexes which don't exist because the list is empty). But this ...

var dictionary = new Dictionary<int, string>()
{
  [0] = "Hello",
  [1] = "World"
};

... is the same as(which adds 2 new entries because it's using this property):

var dictionary = new Dictionary<int, string>();
dictionary[0] = "Hello"; // adds a new dictionary entry with the key 0 and the value "Hello"
dictionary[1] = "World"; // adds a new dictionary entry with the key 1 and the value "World"