web-dev-qa-db-fra.com

Quelles interfaces tous les tableaux implémentent-ils en C #?

En tant que nouveau programmeur .NET 3.5, j'ai commencé à apprendre LINQ et j'ai trouvé quelque chose d'assez basique que je n'avais pas remarqué auparavant:

Le livre prétend que chaque tableau implémente IEnumerable<T> (évidemment, sinon nous ne pourrions pas utiliser LINQ pour les objets sur les tableaux ...). Quand j'ai vu cela, je me suis dit que je n'y avais jamais vraiment pensé et je me suis demandé ce que tous les autres tableaux implémentent. J'ai donc examiné System.Array à l'aide du navigateur d'objets (puisqu'il s'agit de la classe de base de chaque tableau du CLR ) et, à ma grande surprise, il n’implémente pas IEnumerable<T>.

Donc ma question est: où est la définition? Je veux dire, comment puis-je savoir exactement quelles interfaces chaque tableau implémente?

66
ET.

De la documentation (souligné par moi):

[...] la classe Array implémente les interfaces génériques System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T> et System.Collections.Generic.IEnumerable<T>. Les implémentations sont fournies aux baies au moment de l'exécution et ne sont donc pas visibles pour les outils de construction de la documentation.

EDIT: comme le souligne Jb Evain dans son commentaire, seuls les vecteurs (tableaux à une dimension) implémentent les interfaces génériques. En ce qui concerne les pourquoi tableaux multidimensionnels n'implémentent pas les interfaces génériques, je ne suis pas tout à fait sûr, car ils implémentent les équivalents non génériques (voir la déclaration de classe ci-dessous).

La classe System.Array (c'est-à-dire every array) implémente également les interfaces non génériques suivantes:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
68
BoltClock

Vous pouvez trouver la réponse à votre question de manière empirique en utilisant un petit extrait de code:

foreach (var type in (new int[0]).GetType().GetInterfaces())
    Console.WriteLine(type);

L'exécution de l'extrait ci-dessus entraînerait le résultat suivant (sur .NET 4.0):

System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]

(`1 signifie <T>)

62
Hosam Aly

À partir de .NET 4.5, les tableaux implémentent également les interfaces System.Collections.Generic.IReadOnlyList<T> et System.Collections.Generic.IReadOnlyCollection<T> .

Ainsi, en utilisant .NET 4.5, la liste complète des interfaces implémentées par les tableaux devient (obtenue en utilisant la méthode présentée dans réponse de Hosam Aly )

System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

Étrangement, il semble qu'il ait été oublié de mettre à jour le documentation sur MSDN pour mentionner ces deux interfaces.

52
cr7pt0gr4ph7

Soigneusement sur les interfaces de tableaux, ils peuvent les implémenter mais en réalité ils ne le font pas vraiment ... Prenez le code avec le code suivant:

            var x = new int[] { 1, 2, 3, 4, 5 };
        var y = x as IList<int>;
        Console.WriteLine("The IList:" + string.Join(",", y));
        try
        {
            y.RemoveAt(1);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        Console.WriteLine(string.Join(",", y));

Il produit le résultat suivant: result

Donc, l'analyse fonctionne, mais tout n'est pas pris en charge, ce qui est correct du point de vue de la collecte de longueur fixe, mais tout à fait faux si vous croyez vraiment qu'il s'agit d'une liste. Voilà le principe de Liskov de SOLID :(.

Pour tester rapidement cela aidera.

0
Adrian P.

J'ai trouvé l'implémentation de IList<T>, ICollection<T>, IEnumerable<T> dans la classe SZArrayHelper imbriquée du tableau.

Mais je dois vous prévenir - vous y trouverez beaucoup plus de questions ...

La référence

Après cela, je n’en ai plus qu’un - there_is_no_array;)

0
Kamerton