Что произойдет, если я инициализирую массив до размера 0?
Скажем, у меня есть функция вроде:
void myFunc(List<AClass> theList)
{
string[] stuff = new string[theList.Count];
}
и я передаю пустой список.
Будет ли пустой указатель? Или это будет указатель на какое-то случайное место в памяти, которое неинициализировано?
Ответы
Ответ 1
Он создаст пустой объект массива. Это по-прежнему абсолютно корректный объект - и тот, который занимает ненулевое пространство в памяти. Он все равно будет знать свой собственный тип, а счет - просто не будет никаких элементов.
Пустые массивы часто полезны для использования в качестве неизменных пустых коллекций: вы можете повторно использовать их до бесконечности; массивы по своей сути изменяемы, но только с точки зрения их элементов... и здесь у нас нет элементов для изменения! Поскольку массивы не изменяются, пустой массив является абсолютно неизменным.
Обратите внимание, что часто полезно иметь пустой массив вместо нулевой ссылки: методы или свойства, возвращающие коллекции, должны почти всегда возвращать пустую коллекцию, а не пустую ссылку, поскольку она обеспечивает согласованность и единообразие - вместо того, чтобы делать каждую проверку звонящего для недействительности. Если вы хотите избежать выделения более одного раза, вы можете использовать:
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;
(или что-то еще), когда вам нужно использовать ссылку на пустой массив определенного типа.
Ответ 2
Почему? Он просто укажет на массив размером 0, который вполне допустим.
Я думаю, что путаница здесь возникает из-за двусмысленности представления отсутствия данных либо массивом размера 0, либо переменной, установленной в нуль (такая же двусмысленность существует для строк с пустой строкой или набором строк, равным нулю), Оба являются действительными способами указания такого отсутствия, и, возможно, имеет смысл иметь только один. Следовательно, в некоторых базах данных (в частности, Oracle) пустая строка равна значению NULL и наоборот и некоторым языкам программирования (я думаю, что новые версии С# являются одним из них) позволяют указывать ссылки, чтобы никогда не быть нулевыми, также устраняя указанную двусмысленность.
Ответ 3
Это прекрасный код. Вы получите объект Array с нулевыми значениями (распределениями) в нем.
Ответ 4
stuff
будет ссылкой на массив с длиной theList.Count
со всеми записями, инициализированными на default(string)
, который равен null
.
Ответ 5
В спецификации языка С# указано следующее:
- Вычисленные значения для размерных длин проверяются как следующим образом. Если одно или несколько значений меньше нуля, а Исключение System.OverflowException и дальнейшие шаги не выполняются.
- Выделяется экземпляр массива с заданными размерами. Если недостаточно памяти для размещения нового экземпляра Исключение System.OutOfMemoryException и дальнейшие шаги не выполняются.
Итак, для длины нуля выделяется память.
Ответ 6
Linq .Concat
сгенерирует исключение, если любой из аргументов будет нулевым (что может произойти в моем случае). Поэтому я должен был сделать что-то вроде этого в моем коде:
public string[] ConcatUsers(string[] users1, string[] users2)
{
return (users1 ?? new string[0]).Concat(users2 ?? new string[0]).ToArray();
}
(просто пример, где инициализатор массива 0 может быть полезен)
Ответ 7
Если theList
является фактическим объектом List
и просто пуст, то theList.Count
будет возвращать 0. Это означает, что объявление становится
string[] stuff = new string[0];
Другими словами, stuff
будет просто массивом (строк) с длиной 0.
Ответ 8
Пока вы гарантируете, что ваш List < > , который вы фактически передали методу, был инициализирован где-то, например
List<Stuff> myStuff = new List<Stuff>;
список не будет указывать на нуль. Это будет список нулевых предметов.