Чи можливо створити порожній масив без зазначення розміру?
Наприклад, я створив:
String[] a = new String[5];
Чи можемо ми створити вищевказаний масив рядків без розміру?
Чи можливо створити порожній масив без зазначення розміру?
Наприклад, я створив:
String[] a = new String[5];
Чи можемо ми створити вищевказаний масив рядків без розміру?
Відповіді:
Якщо ви збираєтеся використовувати колекцію, яка не знаєш розмір заздалегідь, є кращі варіанти, ніж масиви.
Використовуйте List<string>
натомість - це дозволить вам додати стільки елементів, скільки вам потрібно, і якщо вам потрібно повернути масив, зателефонуйте ToArray()
на змінну.
var listOfStrings = new List<string>();
// do stuff...
string[] arrayOfStrings = listOfStrings.ToArray();
Якщо вам потрібно створити порожній масив, ви можете зробити це:
string[] emptyStringArray = new string[0];
string[]
що немає елементів. Якщо ви спробуєте отримати доступ emptyStringArray[0]
, ви отримаєтеIndexOutOfRangeException
Спробуйте це:
string[] a = new string[] { };
int[] variable = new int[]{}
та використання його, наприклад, у циклі, такому як foreach (var s in variable){ Console.WriteLine(s);}
код, компілюється в: int[] args1 = new int[0];
і foreach (int num in args1){Console.WriteLine(num);}
. Таким чином, не повинно бути різниці між використанням new int[0]
і тим new int[]{}
, що обидва збираються в один і той же код.
var
, хоча тільки для локальних змінних (не для полів). Однак у C # 2.0 (Visual Studio 2005) та новіших версіях вам довелося використовувати синтаксис цієї відповіді (або string[] a = new string[0];
).
У .NET 4.6 кращим способом є використання нового методу Array.Empty
:
String[] a = Array.Empty<string>();
Реалізація є лаконічною, використовуючи як статичні члени в загальних класах поводяться в .NET :
public static T[] Empty<T>()
{
return EmptyArray<T>.Value;
}
// Useful in number of places that return an empty byte array to avoid
// unnecessary memory allocation.
internal static class EmptyArray<T>
{
public static readonly T[] Value = new T[0];
}
(код, пов'язаний з контрактом, видалений для ясності)
Дивись також:
Array.Empty
вихідний код у довідковому джереліArray.Empty<T>()
Enumerable.Empty<T>().ToArray()
Array.Empty<T>()
це НЕ створює масив. Він повертає посилання на попередньо виділений масив.
В оголошенні масиву без розміру немає великого сенсу. Масив приблизно розміром . Коли ви оголошуєте масив конкретного розміру, ви вказуєте фіксовану кількість слотів, доступних у колекції, які вміщують речі, і відповідно розподіляється пам'ять. Щоб додати щось до нього, вам потрібно буде все-таки повторно ініціалізувати існуючий масив (навіть якщо ви змінюєте розмір масиву, див. Цю тему ). Одним з рідкісних випадків, коли ви хочете ініціалізувати порожній масив, буде передавати масив як аргумент.
Якщо ви хочете визначити колекцію, коли ви не знаєте, якого розміру вона може бути, можливо, масив - це не ваш вибір, а щось подібне List<T>
чи подібне.
Однак, єдиний спосіб оголосити масив без зазначення розміру - мати порожній масив розміром 0 . Геманта і Алекса Дн надає два способи. Ще одна простіша альтернатива - це просто :
string[] a = { };
[ Елементи всередині дужки повинні бути неявно перетвореними у визначений тип, наприклад,string[] a = { "a", "b" };
]
Або ще:
var a = Enumerable.Empty<string>().ToArray();
Ось більш декларативний спосіб :
public static class Array<T>
{
public static T[] Empty()
{
return Empty(0);
}
public static T[] Empty(int size)
{
return new T[size];
}
}
Тепер ви можете зателефонувати:
var a = Array<string>.Empty();
//or
var a = Array<string>.Empty(5);
Просто і елегантно!
string[] array = {}
array
на просто a
, як array
це ключове слово, коли з великої літери. Просто погана практика використовувати ім'я ключового слова в якості імені змінної - навіть якщо випадок відрізняється. І в основному те саме, що моя відповідь, за винятком того, що я був String.Empty
там.
a
поганим?
string[] a = new string[0];
або коротке позначення:
string[] a = { };
Зараз кращим способом є:
var a = Array.Empty<string>();
Я написав короткий регулярний вираз , яке можна використовувати в Visual Studio , якщо ви хочете замінити нульову довжину розподіл наприклад new string[0]
. Використовуйте Find (пошук) у Visual Studio із увімкненою опцією Regular Expression:
new[ ][a-zA-Z0-9]+\[0\]
Тепер знайдіть усіх або F3 (Знайдіть далі) і замініть всі на Array.Empty <…> ()!
Ви можете визначити розмір масиву під час виконання .
Це дозволить вам зробити що завгодно, щоб динамічно обчислити розмір масиву. Але, як тільки визначений розмір, непорушний.
Array a = Array.CreateInstance(typeof(string), 5);
int i = 5; string[] a = new string[i];
Я намагався:
string[] sample = new string[0];
Але я міг вставити в неї лише один рядок, і тоді я отримав errorOutOfBound помилку, тому я просто поставив для неї розмір, як
string[] sample = new string[100];
Або інший спосіб, який працює для мене:
List<string> sample = new List<string>();
Призначення значення списку:
sample.Add(your input);
Поєднання пропозицій @nawfal та @Kobi:
namespace Extensions
{
/// <summary> Useful in number of places that return an empty byte array to avoid unnecessary memory allocation. </summary>
public static class Array<T>
{
public static readonly T[] Empty = new T[0];
}
}
Приклад використання:
Array<string>.Empty
ОНОВЛЕННЯ 2019-05-14
(кредити @Jaider ty)
Краще використовувати .Net API:
public static T[] Empty<T> ();
https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8
Відноситься до:
.NET Core: 3.0 Попередній перегляд 5 2.2 2.1 2.0 1.1 1.0
.NET Framework: 4.8 4.7.2 4.7.1 4.7 4.6.2 4.6.1 4.6
.NET Standard: 2.1 Попередній перегляд 2.0 1.6 1.5 1.4 1.3
...
HTH
arr = Array.Empty<string>();
Ви можете зробити:
string[] a = { String.Empty };
Примітка: ОП означало, що не потрібно вказувати розмір, а не робити масив нерозмірним
specify
розміру, не створює масив sizeless
.
Ось приклад справжнього світу. У цьому необхідно ініціалізувати масив foundFiles
спочатку до нульової довжини.
(Як наголошено в інших відповідях: Це ініціалізує не елемент, а особливо не елемент з індексом нуля, тому що це означатиме, що масив мав довжину 1. Масив має нульову довжину після цього рядка!).
Якщо частина = string[0]
опущена, виникає помилка компілятора!
Це через блок вилову без повторного відкидання. Компілятор C # розпізнає шлях коду, що функція Directory.GetFiles()
може кинути виняток, щоб масив міг бути неініціалізованим.
Перш ніж хтось скаже, не повторне скидання винятку було б поганим поводженням з помилками: Це неправда. Помилка керування повинна відповідати вимогам.
У цьому випадку передбачається, що програма повинна продовжуватися у випадку, якщо каталог не може бути прочитаний і не розбитий - найкращим прикладом є функція, що проходить через структуру каталогу. Тут обробка помилок - це просто її реєстрація. Звичайно, це можна зробити краще, наприклад, зібрати всі GetFiles(Dir)
списки каталогів з невдалими дзвінками в список, але це призведе сюди занадто далеко.
Досить констатувати, що уникнення throw
є допустимим сценарієм, і тому масив повинен бути ініціалізований до нульової довжини. Було б достатньо зробити це в блоці ловлі, але це був би поганий стиль.
Виклик зміни GetFiles(Dir)
розміру масиву.
string[] foundFiles= new string[0];
string dir = @"c:\";
try
{
foundFiles = Directory.GetFiles(dir); // Remark; Array is resized from length zero
}
// Please add appropriate Exception handling yourself
catch (IOException)
{
Console.WriteLine("Log: Warning! IOException while reading directory: " + dir);
// throw; // This would throw Exception to caller and avoid compiler error
}
foreach (string filename in foundFiles)
Console.WriteLine("Filename: " + filename);