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?
c#
arrays
initialization
jogurt
źródło
źródło
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łajToArray()
zmienną.Jeśli musisz utworzyć pustą tablicę, możesz to zrobić:
źródło
string[]
że nie ma elementów. Jeśli spróbujesz uzyskać dostępemptyStringArray[0]
, otrzymaszIndexOutOfRangeException
Spróbuj tego:
źródło
int[] variable = new int[]{}
i używania go na przykład w pętli, takiej jakforeach (var s in variable){ Console.WriteLine(s);}
kod, kompiluje się do:int[] args1 = new int[0];
iforeach (int num in args1){Console.WriteLine(num);}
. Dlatego nie powinno być żadnej różnicy między używaniemnew 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 (lubstring[] a = new string[0];
).W .NET 4.6 preferowanym sposobem jest użycie nowej metody
Array.Empty
:Realizacja jest skrótowo, używając jak członkowie statycznych w klasach ogólnych zachowywać w .NET :
(dla przejrzystości usunięto kod związany z umową)
Zobacz też:
Array.Empty
kod źródłowy na Source SourceArray.Empty<T>()
źródło
Enumerable.Empty<T>().ToArray()
Array.Empty<T>()
czy nie utworzyć tablicę. Zwraca referencję do wstępnie przydzielonej tablicy.Możesz zainicjować go z rozmiarem 0, ale będziesz musiał go ponownie zainicjować, gdy wiesz, jaki jest rozmiar, ponieważ nie możesz dołączyć go do tablicy.
źródło
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 :
[ Elementy wewnątrz nawiasu powinny być domyślnie konwertowane na zdefiniowany typ, na przykład
string[] a = { "a", "b" };
]Lub jeszcze jedno:
Oto bardziej deklaratywny sposób :
Teraz możesz zadzwonić:
źródło
Prosty i elegancki!
źródło
array
na justa
, 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 jaString.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 <…> ()!
źródło
Możesz zdefiniować rozmiar tablicy w czasie wykonywania .
Pozwoli ci to zrobić cokolwiek, aby dynamicznie obliczyć rozmiar tablicy. Ale raz zdefiniowany rozmiar jest niezmienny.
źródło
int i = 5; string[] a = new string[i];
Próbowałem:
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
Lub inny sposób, który działa dla mnie:
Przypisywanie wartości do listy:
źródło
Jak wiem, nie możesz zrobić tablicy bez rozmiaru, ale możesz użyć
i potem
l.ToArray()
.źródło
Łącząc sugestie @nawfal i @Kobi:
Przykład użycia:
AKTUALIZACJA 14.05.2019
(podziękowania dla @Jaider ty)
Lepsze wykorzystanie .Net API:
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
źródło
arr = Array.Empty<string>();
Możesz to zrobić:
Uwaga: OP oznaczało, że nie trzeba określać rozmiaru, a tablica nie ma rozmiarów
źródło
specify
rozmiaru, nie tworzenie tablicysizeless
.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.źródło