Est-il possible de créer un tableau vide sans spécifier la taille?
Par exemple, j'ai créé:
String[] a = new String[5];
Pouvons-nous créer le tableau de chaînes ci-dessus sans la taille?
Est-il possible de créer un tableau vide sans spécifier la taille?
Par exemple, j'ai créé:
String[] a = new String[5];
Pouvons-nous créer le tableau de chaînes ci-dessus sans la taille?
Réponses:
Si vous allez utiliser une collection dont vous ne connaissez pas la taille à l'avance, il existe de meilleures options que les tableaux.
Utilisez List<string>
plutôt un - il vous permettra d'ajouter autant d'éléments que nécessaire et si vous avez besoin de retourner un tableau, appelez ToArray()
la variable.
var listOfStrings = new List<string>();
// do stuff...
string[] arrayOfStrings = listOfStrings.ToArray();
Si vous devez créer un tableau vide, vous pouvez le faire:
string[] emptyStringArray = new string[0];
string[]
qui n'a aucun élément. Si vous essayez d'accéder emptyStringArray[0]
, vous obtiendrez unIndexOutOfRangeException
Essaye ça:
string[] a = new string[] { };
int[] variable = new int[]{}
et l'utiliser par exemple dans une boucle telle que foreach (var s in variable){ Console.WriteLine(s);}
le code est compilé en: int[] args1 = new int[0];
et foreach (int num in args1){Console.WriteLine(num);}
. Il ne devrait donc pas y avoir de différence entre l'utilisation de new int[0]
et new int[]{}
car les deux sont compilés dans le même code.
var
, mais uniquement pour les variables locales (pas pour les champs). Cependant, en C # 2.0 (Visual Studio 2005) et versions antérieures, vous deviez utiliser la syntaxe de cette réponse (ou string[] a = new string[0];
).
Dans .NET 4.6, la méthode préférée consiste à utiliser une nouvelle méthode Array.Empty
:
String[] a = Array.Empty<string>();
L' implémentation est succincte, en utilisant comment les membres statiques dans les classes génériques se comportent dans .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];
}
(code lié au contrat de code supprimé pour plus de clarté)
Voir également:
Array.Empty
code source sur la source de référenceArray.Empty<T>()
Enumerable.Empty<T>().ToArray()
Array.Empty<T>()
ne crée pas de tableau. Il renvoie une référence à un tableau pré-alloué.
Il ne sert à rien de déclarer un tableau sans taille. Un tableau est de taille environ . Lorsque vous déclarez un tableau de taille spécifique, vous spécifiez le nombre fixe d'emplacements disponibles dans une collection pouvant contenir des éléments, et en conséquence la mémoire est allouée. Pour y ajouter quelque chose, vous devrez de toute façon réinitialiser le tableau existant (même si vous redimensionnez le tableau, consultez ce fil ). L'un des rares cas où vous voudriez initialiser un tableau vide serait de passer le tableau en argument.
Si vous souhaitez définir une collection lorsque vous ne savez pas de quelle taille elle pourrait être, le tableau n'est pas votre choix, mais quelque chose comme un List<T>
ou similaire.
Cela dit, la seule façon de déclarer un tableau sans spécifier de taille est d'avoir un tableau vide de taille 0 . hemant et Alex Dn proposent deux méthodes. Une autre alternative plus simple consiste à :
string[] a = { };
[ Les éléments à l'intérieur du support doivent être implicitement convertibles en type défini, par exemple,string[] a = { "a", "b" };
]
Ou encore un autre:
var a = Enumerable.Empty<string>().ToArray();
Voici une manière plus déclarative :
public static class Array<T>
{
public static T[] Empty()
{
return Empty(0);
}
public static T[] Empty(int size)
{
return new T[size];
}
}
Vous pouvez maintenant appeler:
var a = Array<string>.Empty();
//or
var a = Array<string>.Empty(5);
Simple et élégant!
string[] array = {}
array
simplement a
, tout comme array
un mot-clé une fois capitalisé. Juste une mauvaise pratique pour utiliser un nom de mot clé comme nom de variable - même si le cas est différent. Et fondamentalement la même que ma réponse, sauf que j'avais String.Empty
là-dedans.
a
c'est mauvais?
string[] a = new string[0];
ou notation courte:
string[] a = { };
La voie préférée est maintenant:
var a = Array.Empty<string>();
J'ai écrit une expression régulière courte que vous pouvez utiliser dans Visual Studio si vous souhaitez remplacer des allocations de longueur nulle, par exemple new string[0]
. Utilisez la recherche (recherche) dans Visual Studio avec l'option Expression régulière activée:
new[ ][a-zA-Z0-9]+\[0\]
Maintenant, trouvez tout ou F3 (Rechercher suivant) et remplacez tout par Array.Empty <…> ()!
Vous pouvez définir la taille du tableau lors de l'exécution .
Cela vous permettra de faire n'importe quoi pour calculer dynamiquement la taille du tableau. Mais, une fois définie, la taille est immuable.
Array a = Array.CreateInstance(typeof(string), 5);
int i = 5; string[] a = new string[i];
J'avais essayé:
string[] sample = new string[0];
Mais je ne pouvais y insérer qu'une chaîne, puis j'ai eu une erreur exceptionOutOfBound, donc j'ai simplement mis une taille pour cela, comme
string[] sample = new string[100];
Ou une autre façon qui fonctionne pour moi:
List<string> sample = new List<string>();
Attribution d'une valeur à la liste:
sample.Add(your input);
Combiner les suggestions @nawfal et @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];
}
}
Exemple d'utilisation:
Array<string>.Empty
MISE À JOUR 2019-05-14
(crédits à @Jaider ty)
Meilleure utilisation de l'API .Net:
public static T[] Empty<T> ();
https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netframework-4.8
S'applique à:
.NET Core: 3.0 Aperçu 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 Aperçu 2.0 1.6 1.5 1.4 1.3
...
HTH
arr = Array.Empty<string>();
Tu peux faire:
string[] a = { String.Empty };
Remarque: OP signifiait ne pas avoir à spécifier de taille, pas à rendre un tableau sans taille
specify
taille, pas faire de tableau sizeless
.
Voici un exemple du monde réel. En cela, il est nécessaire d'initialiser le tableaufoundFiles
abord à une longueur nulle.
(Comme souligné dans d'autres réponses: cela n'initialise pas un élément et surtout pas un élément d'index zéro car cela signifierait que le tableau avait une longueur 1. Le tableau a une longueur nulle après cette ligne!).
Si la partie = string[0]
est omise, il y a une erreur de compilation!
C'est à cause du bloc catch sans rethrow. Le compilateur C # reconnaît le chemin de code, que la fonction Directory.GetFiles()
peut lever une exception, afin que le tableau puisse être non initialisé.
Avant que quelqu'un ne le dise, ne pas lever l'exception serait une mauvaise gestion des erreurs: ce n'est pas vrai. La gestion des erreurs doit répondre aux exigences.
Dans ce cas, il est supposé que le programme doit continuer dans le cas d'un répertoire qui ne peut pas être lu, et ne pas casser - le meilleur exemple est une fonction traversant une structure de répertoire. Ici, la gestion des erreurs consiste simplement à l'enregistrer. Bien sûr, cela pourrait être mieux fait, par exemple en collectant tous les répertoiresGetFiles(Dir)
appels dans une liste, mais cela mènera trop loin ici.
Il suffit d'indiquer que l'évitement throw
est un scénario valide, et donc le tableau doit être initialisé à la longueur zéro. Il suffirait de le faire dans le bloc catch, mais ce serait un mauvais style.
L'appel à GetFiles(Dir)
redimensionner le tableau.
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);