2010-03-31 10 views
6

System.Array sert de classe de base pour tous les tableaux du Common Language Runtime (CLR). Selon this article:Où puis-je trouver des informations sur les méthodes Get, Set et Address pour les instances System.Array multidimensionnelles dans .NET?

Pour chaque type de tableau concret, [la] exécution ajoute trois méthodes spéciales: Get/Set/Address.

et même si je démonte ce code C#,

int[,] x = new int[1024,1024]; 
x[0,0] = 1; 
x[1,1] = 2; 
x[2,2] = 3; 
Console.WriteLine(x[0,0]); 
Console.WriteLine(x[1,1]); 
Console.WriteLine(x[2,2]); 

en CIL que je reçois,

IL_0000: ldc.i4  0x400 
IL_0005: ldc.i4  0x400 
IL_000a: newobj  instance void int32[0...,0...]::.ctor(int32, 
                 int32) 
IL_000f: stloc.0 
IL_0010: ldloc.0 
IL_0011: ldc.i4.0 
IL_0012: ldc.i4.0 
IL_0013: ldc.i4.1 
IL_0014: call  instance void int32[0...,0...]::Set(int32, 
                 int32, 
                 int32) 
IL_0019: ldloc.0 
IL_001a: ldc.i4.1 
IL_001b: ldc.i4.1 
IL_001c: ldc.i4.2 
IL_001d: call  instance void int32[0...,0...]::Set(int32, 
                 int32, 
                 int32) 
IL_0022: ldloc.0 
IL_0023: ldc.i4.2 
IL_0024: ldc.i4.2 
IL_0025: ldc.i4.3 
IL_0026: call  instance void int32[0...,0...]::Set(int32, 
                 int32, 
                 int32) 
IL_002b: ldloc.0 
IL_002c: ldc.i4.0 
IL_002d: ldc.i4.0 
IL_002e: call  instance int32 int32[0...,0...]::Get(int32, 
                 int32) 
IL_0033: call  void [mscorlib]System.Console::WriteLine(int32) 
IL_0038: ldloc.0 
IL_0039: ldc.i4.1 
IL_003a: ldc.i4.1 
IL_003b: call  instance int32 int32[0...,0...]::Get(int32, 
                 int32) 
IL_0040: call  void [mscorlib]System.Console::WriteLine(int32) 
IL_0045: ldloc.0 
IL_0046: ldc.i4.2 
IL_0047: ldc.i4.2 
IL_0048: call  instance int32 int32[0...,0...]::Get(int32, 
                 int32) 
IL_004d: call  void [mscorlib]System.Console::WriteLine(int32) 

où les appels vers les Get et Set susmentionnés méthodes peuvent être clairement visibles. Il semble que l'arité de ces méthodes est liée à la dimensionnalité du tableau, ce qui est probablement la raison pour laquelle elles sont créées par le moteur d'exécution et ne sont pas pré-déclarées. Je ne pouvais pas trouver d'informations sur ces méthodes sur MSDN et leurs noms simples les rend résistants à Google. J'écris un compilateur pour un langage qui supporte des tableaux multidimensionnels, donc j'aimerais trouver de la documentation officielle sur ces méthodes, sous quelles conditions je peux m'attendre à ce qu'elles existent et à ce que je peux attendre de leurs signatures.

En particulier, je voudrais savoir s'il est possible d'obtenir un objet MethodInfo pour Get ou Set pour une utilisation avec Reflection.Emit sans avoir à créer une instance du tableau avec le type correct et dimensionnalité sur lequel réfléchir, comme cela est fait dans l'exemple lié.

+0

@Rob: avez-vous un exemple pour la méthode 'Address'? Et avez-vous un lien décrivant le fait que ces méthodes sont générées? –

+0

@John - si vous cliquez sur le lien 'cet article' dans mon paragraphe d'ouverture, vous finirez par l'article à partir duquel la citation dans le deuxième paragraphe est prise. –

Répondre

5

Regardez ici, en particulier l'article 14.2 sur les pages 63-65

http://download.microsoft.com/download/7/3/3/733AD403-90B2-4064-A81E-01035A7FE13C/MS%20Partition%20II.pdf

Mais les plats à emporter, et vous pouvez dire de l'IL, est qu'ils sont les méthodes getter et setter pour traiter les tableaux aux positions d'indice données.

• Une méthode Get qui prend une séquence de arguments Int32, un pour chaque dimension du réseau , et renvoie une valeur dont le type est le type d'élément de la matrice. Cette méthode est utilisée pour accéder à un élément spécifique du tableau où les arguments spécifient l'index dans chaque dimension, en commençant par le premier, de l'élément à retourné.

• Un ensemble méthode qui prend une séquence d'arguments Int32, un pour chaque dimension de la matrice, suivi d'une valeur dont le type est le type d'élément de la matrice. Le type de retour de l'ensemble est nul.Cette méthode est utilisée pour définir un élément spécifique de la matrice où les arguments précisent l'index dans chaque dimension, en commençant par la première, de l'élément à régler et le dernier argument spécifie la valeur à stocker dans l'élément cible.

• Une méthode d'adresses qui prend une séquence d'arguments Int32, une pour chaque dimension de la matrice, et a un type de retour qui est un pointeur géré au type d'élément de la matrice. Cette méthode est utilisée pour renvoyer un pointeur réussi à un élément spécifique du réseau où les arguments précisent l'indice dans chaque dimension, en commençant avec le premier , de l'élément dont l'adresse est à retourner.

Edit: pages de 63-65 Que l'aide de la numérotation des pages du document. 73-75 dans le PDF actuel.

+0

Excellent! C'est exactement ce que je cherchais. Je vous remercie. –

1

Je ne sais pas si cela va répondre à votre question très spécifique, mais un bon texte sur le sujet (entre autres) est CLR via C#. Il devient très approfondi pour de nombreux sujets qui vous intéressent et passe beaucoup de temps avec le désassembleur en regardant les rouages ​​internes de nombreux types .NET de base, y compris les tableaux. Vaut vraiment le détour.

+0

Merci de me rappeler de regarder CLR via C#, que j'ai ici. Je viens de lire le chapitre 13: Arrays mais je ne vois aucune mention des méthodes Get, Set et Address. –

2

Pour répondre à votre deuxième question, vous n'avez pas besoin de créer une instance pour obtenir un MethodInfo pour ces méthodes. Quelque chose comme

var mi = typeof(string).MakeArrayType(6).GetMethod("Get"); 

travaillera pour obtenir la méthode Get pour le type string[,,,,,].

+0

Splendide! Maintenant, j'ai tout ce que je suis venu chercher. –

+1

J'ai par la suite découvert que le soin est nécessaire lors de la sélection entre les surcharges de MakeArrayType. Sans arguments - MakeArrayType() crée un type de vecteur tel que string []. Avec un argument de one - MakeArrayType (1) crée un tableau multidimensionnel avec une dimension de type string [*]. Ces types ne sont pas compatibles. Pour l'interopérabilité avec les autres langages .NET, cela signifie que lorsque rank == 1 vous aurez besoin de cas particulier l'appel à la méthode sans paramètre. –