Скажем, у меня есть функция как:
void myFunc(List<AClass> theList)
{
string[] stuff = new string[theList.Count];
}
и я передаю в пустом списке.
Материал будет нулевым указателем? Или это будет указатель на некоторое случайное место в памяти, которая является неинициализированной?
Будет создан пустой объект массива. Это по-прежнему вполне допустимый объект, который занимает ненулевое пространство в памяти. Он по-прежнему будет знать свой собственный тип и счетчик - у него просто не будет никаких элементов.
Пустые массивы часто полезно использовать в качестве неизменяемых пустых коллекций: вы можете использовать их до бесконечности; массивы по своей сути изменчивы, но только в терминах их элементов ... и здесь у нас нет элементов, которые нужно изменить! Поскольку размер массивов нельзя изменить, пустой массив полностью неизменен.
Обратите внимание, что часто бывает полезно иметь пустой массив вместо нулевой ссылки: методы или свойства, возвращающие коллекции, должны почти всегда возвращать пустую коллекцию, а не нулевую ссылку, поскольку это обеспечивает согласованность и единообразие - вместо того, чтобы делать проверку каждого вызывающего абонента на недействительность. Если вы хотите избежать выделения более одного раза, вы можете использовать:
public static class Arrays<T>
{
private static readonly T[] empty = new T[0];
public static readonly T[] Empty { get { return empty; } }
}
Затем вы можете просто использовать:
return Arrays<string>.Empty;
(или что-то еще), когда вам нужно использовать ссылку на пустой массив определенного типа.
Это хороший код. Вы получите объект Array с нулевыми элементами (выделениями) в нем.
Зачем? Он просто укажет на массив размером 0, что совершенно верно.
Я думаю, что путаница здесь возникает из-за неоднозначности представления отсутствия данных либо массивом размера 0, либо переменной, установленной в значение NULL (такая же неоднозначность существует для строк с пустой строкой или для ссылки на строку, установленной в значение NULL) . Оба являются допустимыми способами указать на такое отсутствие, и, возможно, было бы разумнее иметь только один. Следовательно, в некоторых базах данных (в частности, Oracle) пустая строка равна значению NULL и наоборот, а некоторые языки программирования (я думаю, что новые версии C # являются одним из них) позволяют указывать ссылки, которые никогда не будут нулевыми, что также устраняет указанную двусмысленность.
stuff
будет ссылкой на массив длиной theList.Count
со всеми записями, инициализированными значением default (string)
, то есть null
.
В спецификации языка C # указано следующее:
- Вычисленные значения длин измерений проверяются как следует. Если одно или несколько значений меньше нуля, a System.OverflowException выбрасывается и дальнейшие шаги не выполняются.
- Выделяется экземпляр массива с заданной длиной измерения. Если недостаточно памяти чтобы выделить новый экземпляр, System.OutOfMemoryException выбрасывается и никакие дальнейшие шаги не выполняются.
Таким образом, для нулевой длины выделяется память.
Если theList
является фактическим объектом List
и просто пустым, то theList.Count
вернет 0. Это означает, что объявление становится
string[] stuff = new string[0];
Другими словами, stuff
будет просто массивом (строк) с длиной 0.
До тех пор, пока вы убедитесь, что ваш List<>, который вы фактически передаете в метод, был где-то инициализирован, например
List<Stuff> myStuff = new List<Stuff>;
список не будет указывать на null. Это будет список из нулевых Stuffs.