Различие в инициализации коллекции List обычным способом и через индексацию

196
04 марта 2018, 21:21

Просто приведу два кусочка кода, которые должны быть идентичны по реализации.

Users.users = new List<User>
                              {
                                 [0] = Users.Admin
                              }; // Исключение
Users.users = new List<User>
                              {
                                 Users.Admin
                              }; // Все ок

Если что, это файл Data\Users.cs

Текст исключения:

System.ArgumentOutOfRangeException: Индекс за пределами диапазона. Индекс должен быть положительным числом, а его размер не должен превышать размер коллекции. Имя параметра: index

Различия - только в том кусочке кода, что я привел в начале вопроса.

Вот ссылка на проект на Git: Проект на git

Папка с exe, где вроде все ок: https://yadi.sk/d/N6tfBD0Y3SyNFW

Папка с exe, где исключение: https://yadi.sk/d/N6tfBD0Y3SyNFW

Как проявить это проблемное место:

  1. Запустите exe (откроется окно типа "О программе")
  2. Удалите папку Records, которая создалась рядом с экзешником
  3. Закройте окно, обратите внимание на исключение.
  4. Попробуйте проделать то же самое с "Хорошим" экзешником.

Так вот, откуда взялись различия, если код, по идее, не отличается?

Answer 1

Что ж, я нашел ответ. Инициализация индексированных элементов, как здесь

var numbers = new Dictionary<int, string> {   
[7] = "seven",   
[9] = "nine",   
[13] = "thirteen"   
}; 

- это для словарей. После создания словаря вызывается метод Add(key, value), который и добавляет в словарь новый элемент. В случае же с List : после создания нового List вызывается метод Set(index, value), который не может присвоить значение из-за того, что index == размеру коллекции.

Если кто-то поймет IL код, то IL кода для этого участка кода

var list = new List<string>
                       {
                          [0] = "Hello"
                       };
        var dict = new Dictionary<string, string>
                       {
                          [string.Empty] = "That's cool"
                       };

Будет таким:

// [183 13 - 186 30] 
IL_0000: newobj       instance void class [mscorlib]System.Collections.Generic.List`1<string>::.ctor()
IL_0005: dup          
IL_0006: ldc.i4.0     
IL_0007: ldstr        "Hello"
IL_000c: callvirt     instance void class [mscorlib]System.Collections.Generic.List`1<string>::set_Item(int32, !0/*string*/)
IL_0011: pop          
// [188 13 - 191 30]
IL_0012: newobj       instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string, string>::.ctor()
IL_0017: ldsfld       string [mscorlib]System.String::Empty
IL_001c: stloc.0      // V_0
IL_001d: dup          
IL_001e: ldloc.0      // V_0
IL_001f: ldstr        "That's cool"
IL_0024: callvirt     instance void class [mscorlib]System.Collections.Generic.Dictionary`2<string, string>::set_Item(!0/*string*/, !1/*string*/)
IL_0029: pop  
READ ALSO
Определение высоты и ширины ListBoxItem

Определение высоты и ширины ListBoxItem

Необходимо получить высоту элементов ListBox'a с кастомным DataTemplate'омВ ListBox элементы добавляются с использование класса, в котором и должны быть...

185
c# wpf не могу подключить System.Windows.Forms

c# wpf не могу подключить System.Windows.Forms

хочу сделать иконку в трее, в инструкциях пишут добавить using SystemWindows

196
Как будет выглядеть Mat после Mat = Mat*Mat &gt; 0 в OpenCV?

Как будет выглядеть Mat после Mat = Mat*Mat > 0 в OpenCV?

У меня есть кусок кода, который нужно переписать на с#, но мне не понятна вот эта конструкция

203
Как контролировать скрытые элементы?

Как контролировать скрытые элементы?

Написал метод который скрывает элементы, как можно обойти checkbox?

213