Подтвердить что ты не робот

Что произойдет, если я инициализирую массив до размера 0?

Скажем, у меня есть функция вроде:

void myFunc(List<AClass> theList)
{
   string[] stuff = new string[theList.Count];
}

и я передаю пустой список.

Будет ли пустой указатель? Или это будет указатель на какое-то случайное место в памяти, которое неинициализировано?

4b9b3361

Ответ 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>;

список не будет указывать на нуль. Это будет список нулевых предметов.