Czy można utworzyć pustą tablicę bez określania rozmiaru?
Na przykład utworzyłem:
String[] a = new String[5];
Czy możemy utworzyć powyższą tablicę ciągów bez rozmiaru?
Czy można utworzyć pustą tablicę bez określania rozmiaru?
Na przykład utworzyłem:
String[] a = new String[5];
Czy możemy utworzyć powyższą tablicę ciągów bez rozmiaru?
Odpowiedzi:
Jeśli zamierzasz użyć kolekcji, której nie znasz z góry, istnieją lepsze opcje niż tablice.
Użyj List<string>
zamiast tego - pozwoli ci dodać tyle elementów, ile potrzebujesz, a jeśli musisz zwrócić tablicę, wywołaj ToArray()
zmienną.
var listOfStrings = new List<string>();
// do stuff...
string[] arrayOfStrings = listOfStrings.ToArray();
Jeśli musisz utworzyć pustą tablicę, możesz to zrobić:
string[] emptyStringArray = new string[0];
string[]
że nie ma elementów. Jeśli spróbujesz uzyskać dostęp emptyStringArray[0]
, otrzymaszIndexOutOfRangeException
Spróbuj tego:
string[] a = new string[] { };
int[] variable = new int[]{}
i używania go na przykład w pętli, takiej jak foreach (var s in variable){ Console.WriteLine(s);}
kod, kompiluje się do: int[] args1 = new int[0];
i foreach (int num in args1){Console.WriteLine(num);}
. Dlatego nie powinno być żadnej różnicy między używaniem new int[0]
a tym, new int[]{}
że oba są kompilowane do tego samego kodu.
var
, chociaż tylko dla zmiennych lokalnych (nie dla pól). Jednak w C # 2.0 (Visual Studio 2005) i wcześniejszych trzeba było użyć składni tej odpowiedzi (lub string[] a = new string[0];
).
W .NET 4.6 preferowanym sposobem jest użycie nowej metody Array.Empty
:
String[] a = Array.Empty<string>();
Realizacja jest skrótowo, używając jak członkowie statycznych w klasach ogólnych zachowywać w .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];
}
(dla przejrzystości usunięto kod związany z umową)
Zobacz też:
Array.Empty
kod źródłowy na Source SourceArray.Empty<T>()
Enumerable.Empty<T>().ToArray()
Array.Empty<T>()
czy nie utworzyć tablicę. Zwraca referencję do wstępnie przydzielonej tablicy.
Deklarowanie tablicy bez rozmiaru nie ma większego sensu. Tablica jest o rozmiarze . Deklarując tablicę o określonym rozmiarze, określasz stałą liczbę dostępnych w zbiorze miejsc, które mogą pomieścić różne rzeczy, i odpowiednio przydzielana jest pamięć. Aby coś do niego dodać, musisz zresetować istniejącą tablicę (nawet jeśli zmieniasz rozmiar tablicy, zobacz ten wątek ). Jednym z rzadkich przypadków, w których chcesz zainicjować pustą tablicę, jest przekazanie tablicy jako argumentu.
Jeśli chcesz zdefiniować kolekcję, gdy nie wiesz, jaki to może być rozmiar, tablica nie jest Twoim wyborem, ale czymś podobnym List<T>
lub podobnym.
To powiedziawszy, jedynym sposobem zadeklarowania tablicy bez określania rozmiaru jest pusta tablica o rozmiarze 0 . hemant i Alex Dn zapewniają dwa sposoby. Inną prostszą alternatywą jest po prostu :
string[] a = { };
[ Elementy wewnątrz nawiasu powinny być domyślnie konwertowane na zdefiniowany typ, na przykładstring[] a = { "a", "b" };
]
Lub jeszcze jedno:
var a = Enumerable.Empty<string>().ToArray();
Oto bardziej deklaratywny sposób :
public static class Array<T>
{
public static T[] Empty()
{
return Empty(0);
}
public static T[] Empty(int size)
{
return new T[size];
}
}
Teraz możesz zadzwonić:
var a = Array<string>.Empty();
//or
var a = Array<string>.Empty(5);
Prosty i elegancki!
string[] array = {}
array
na just a
, ponieważ array
jest to słowo kluczowe przy pisaniu wielkimi literami. Po prostu zła praktyka używania nazwy słowa kluczowego jako nazwy zmiennej - nawet jeśli wielkość liter jest inna. I w zasadzie taka sama jak moja odpowiedź, tyle że ja String.Empty
tam miałem .
a
jest źle?
string[] a = new string[0];
lub krótki zapis:
string[] a = { };
Preferowanym sposobem jest teraz:
var a = Array.Empty<string>();
Napisałem krótkie wyrażenie regularne, którego możesz użyć w Visual Studio, jeśli chcesz zastąpić przydziały zerowej długości, np new string[0]
. Użyj Znajdź (wyszukaj) w Visual Studio z włączoną opcją Wyrażenie regularne:
new[ ][a-zA-Z0-9]+\[0\]
Teraz Znajdź wszystko lub F3 (Znajdź następny) i zamień wszystko na Array.Empty <…> ()!
Możesz zdefiniować rozmiar tablicy w czasie wykonywania .
Pozwoli ci to zrobić cokolwiek, aby dynamicznie obliczyć rozmiar tablicy. Ale raz zdefiniowany rozmiar jest niezmienny.
Array a = Array.CreateInstance(typeof(string), 5);
int i = 5; string[] a = new string[i];
Próbowałem:
string[] sample = new string[0];
Ale mogłem wstawić tylko jeden ciąg, a następnie wystąpił błąd wyjątku OutOfBound, więc po prostu ustawiłem dla niego rozmiar, na przykład
string[] sample = new string[100];
Lub inny sposób, który działa dla mnie:
List<string> sample = new List<string>();
Przypisywanie wartości do listy:
sample.Add(your input);
Łącząc sugestie @nawfal i @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];
}
}
Przykład użycia:
Array<string>.Empty
AKTUALIZACJA 14.05.2019
(podziękowania dla @Jaider ty)
Lepsze wykorzystanie .Net API:
public static T[] Empty<T> ();
https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8
Dotyczy:
.NET Core: 3.0 Preview 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 Preview 2.0 1.6 1.5 1.4 1.3
...
HTH
arr = Array.Empty<string>();
Możesz to zrobić:
string[] a = { String.Empty };
Uwaga: OP oznaczało, że nie trzeba określać rozmiaru, a tablica nie ma rozmiarów
specify
rozmiaru, nie tworzenie tablicy sizeless
.
Oto przykład ze świata rzeczywistego. W tym celu konieczne jest zainicjowanie tablicy foundFiles
najpierw do zera długości.
(Jak podkreślono w innych odpowiedziach: To nie inicjuje elementu, a zwłaszcza elementu o indeksie zero, ponieważ oznaczałoby to, że tablica ma długość 1. Tablica ma zerową długość po tej linii!).
Jeśli część = string[0]
zostanie pominięta, wystąpi błąd kompilatora!
Wynika to z blokady zaczepu bez ponownego rzucania. Kompilator C # rozpoznaje ścieżkę kodu, że funkcja Directory.GetFiles()
może zgłosić wyjątek, aby tablica mogła zostać niezainicjowana.
Zanim ktokolwiek powie, brak ponownego zgłoszenia wyjątku byłby złym sposobem obsługi błędów: To nie jest prawda. Obsługa błędów musi spełniać wymagania.
W takim przypadku zakłada się, że program powinien kontynuować w przypadku katalogu, którego nie można odczytać, a nie złamać - najlepszym przykładem jest funkcja przechodząca przez strukturę katalogów. Tutaj obsługa błędów polega tylko na logowaniu. Oczywiście można to zrobić lepiej, np. Zbierając wszystkie katalogi z nieudanymi GetFiles(Dir)
połączeniami na liście, ale doprowadzi to zbyt daleko tutaj.
Wystarczy stwierdzić, że unikanie throw
jest prawidłowym scenariuszem, więc tablica musi zostać zainicjowana do długości zero. Wystarczyłoby to zrobić w bloku catch, ale byłby to zły styl.
Wywołanie zmiany GetFiles(Dir)
rozmiaru tablicy.
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);