66 votes

Que se passe-t-il si j'initialise un tableau à la taille 0 ?

Disons que j'ai une fonction comme :

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

et je passe dans une liste vide.

Le truc sera-t-il un pointeur nul ? Ou sera-t-il un pointeur vers un endroit aléatoire de la mémoire qui n'est pas initialisé ?

1 votes

C'est très utile lorsque vous avez besoin d'un IEnumerable<T> vide (généralement pour les tests).

8 votes

Enumerable.Empty<...> est encore mieux.

108voto

Jon Skeet Points 692016

Cela créera un objet tableau vide. Il s'agit toujours d'un objet parfaitement valide - et qui occupe une quantité non nulle d'espace en mémoire. Il connaîtra toujours son propre type, et le nombre d'éléments - il n'aura simplement aucun élément.

Les tableaux vides sont souvent utiles en tant que collections vides immuables : vous pouvez les réutiliser à l'infini ; les tableaux sont intrinsèquement mutables mais uniquement en termes de leur éléments ... et ici nous n'avons aucun élément à modifier ! Comme les tableaux ne sont pas redimensionnables, un tableau vide est aussi immuable qu'un objet peut l'être en .NET.

Notez qu'il est souvent utile d'avoir un tableau vide au lieu d'une référence nulle : les méthodes ou les propriétés retournant des collections devraient presque toujours avoir une référence nulle. toujours renvoient une collection vide plutôt qu'une référence nulle, car cela permet d'assurer la cohérence et l'uniformité - plutôt que de rendre les chaque l'appelant vérifie la nullité. Si vous voulez éviter d'allouer plus d'une fois, vous pouvez utiliser :

public static class Arrays<T>
{
    private static readonly T[] empty = new T[0];

    public static readonly T[] Empty { get { return empty; } }
}

Alors vous pouvez simplement utiliser :

return Arrays<string>.Empty;

(ou autre) lorsque vous avez besoin d'utiliser une référence à un tableau vide d'un type particulier.

1 votes

Le point clé sur lequel j'étais confus était de savoir si un tableau vide prend une quantité d'espace non nulle, comme vous l'appelez.

2 votes

Comme l'information sur sa "vacuité" doit être stockée quelque part (c'est-à-dire le nombre), elle doit prendre de la place. Compte tenu de ce que j'ai écrit dans ma réponse, vous pourriez bien sûr (mais c'est dangereux) avoir comme ligne directrice interne qu'au lieu d'initialiser des tableaux de longueur 0, vous mettez la référence à null. Mais cela peut nécessiter des vérifications supplémentaires lorsque de tels tableaux sont utilisés et ne vaut pas la peine de gagner un peu d'espace.

0 votes

Je ne comprends toujours pas la raison pour laquelle tu voudrais quelque chose comme new int[0]; . Je ne vois pas comment il peut servir à quelque chose puisque c'est immuable.

12voto

Janick Bernet Points 6465

Pourquoi le devrait-elle ? Il pointera simplement vers un tableau de taille 0, ce qui est parfaitement valide.

Je pense que la confusion provient de l'ambiguïté de représenter l'absence de données soit par un tableau de taille 0, soit par une variable définie comme nulle (la même ambiguïté existe pour les chaînes de caractères avec une chaîne vide ou une référence de chaîne définie comme nulle). Les deux moyens sont valables pour indiquer une telle absence et il serait sans doute plus logique de n'en avoir qu'un seul. Ainsi, sur certaines bases de données (Oracle en particulier), une chaîne vide équivaut à la valeur NULL et vice versa, et certains langages de programmation (je pense que les nouvelles versions de C# en font partie) permettent de spécifier que les références ne sont jamais nulles, ce qui élimine également ladite ambiguïté.

1 votes

"Les deux indiquent l'absence de données et il n'y a pas de bonne ou de mauvaise façon d'indiquer cette absence." Mais conceptuellement, il y a généralement une différence entre les deux. C'est comme la différence entre avoir une boîte en carton vide et ne pas avoir de boîte du tout. (J'espère ne jamais avoir à travailler avec des bases de données où "" == NULL, car cela me rendrait assez confus).

0 votes

Oracle le fait apparemment. Je ne suis pas non plus d'accord à 100% avec cela, à cause de la logique terinaire (IS NULL vs = NULL).

3 votes

NULL == "" est une "fonctionnalité" maléfique d'Oracle - aucun système sain ne devrait généralement les traiter de la même manière. Mon opinion...^^

5voto

Brian Genisio Points 30777

C'est un bon code. Vous obtiendrez un objet Array avec zéro élément (allocations) à l'intérieur.

3voto

dahlbyk Points 24897

stuff sera une référence à un tableau de longueur theList.Count avec toutes les entrées initialisées à default(string) qui est null .

1 votes

Ce qu'il voulait dire, c'est que vous lui passez une liste vide, c'est-à-dire que theList.Count vaut 0. Cela signifie bien sûr qu'il n'y aura aucune entrée initialisée à quoi que ce soit.

5 votes

Dans ce cas, ce sera une référence à un tableau de longueur 0 avec toutes les entrées 0 initialisées à null ;)

2voto

Ce qui suit se trouve dans la spécification du langage C# :

  • Les valeurs calculées pour les longueurs des dimensions sont validées comme suit comme suit. Si une ou plusieurs de ces valeurs sont inférieures à zéro, une System.OverflowException est déclenchée et aucune autre étape n'est exécutée.
  • Une instance de tableau avec les longueurs de dimension données est allouée. Si il n'y a pas assez de mémoire disponible pour allouer la nouvelle instance, un message System.OutOfMemoryException est levée et aucune autre étape n'est exécutée.

Ainsi, pour une longueur de zéro, la mémoire est allouée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X