2010-03-31 7 views
6

System.Array funge da classe base per tutti gli array nel Common Language Runtime (CLR). Secondo this article:Dove posso trovare informazioni sui metodi Get, Set e Address per istanze multidimensionali di System.Array in .NET?

Per ciascun tipo di matrice di cemento, [la] runtime aggiunge tre metodi speciali: Get/Set/Address.

e anzi se mi smontare il # codice 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]); 

in CIL ricevo,

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) 

in cui le chiamate ai predetti Get e Set metodi possono essere chiaramente visibili. Sembra che l'arità di questi metodi sia correlata alla dimensionalità dell'array, che presumibilmente è il motivo per cui sono creati dal runtime e non sono pre-dichiarati. Non sono riuscito a trovare alcuna informazione su questi metodi su MSDN e il loro semplice nome li rende resistenti a Google. Sto scrivendo un compilatore per un linguaggio che supporta array multidimensionali, quindi mi piacerebbe trovare una documentazione ufficiale su questi metodi, a quali condizioni posso aspettarmi che esistano e su cosa posso aspettarmi che siano le loro firme.

In particolare, vorrei sapere se la sua possibile ottenere un oggetto MethodInfo per Get o Set per l'uso con Reflection.Emit senza dover creare un'istanza della matrice con il tipo corretto e dimensionalità su cui riflettere, come è fatto nell'esempio collegato.

+0

@Rob: hai un esempio per il metodo 'Address'? E hai un link che descrive il fatto che questi metodi sono generati? –

+0

@John - se si fa clic sul collegamento "questo articolo" nel mio paragrafo iniziale, si finisce nell'articolo da cui viene presa la citazione nel secondo paragrafo. –

risposta

5

Guardate qui, in particolare la sezione 14.2 a pagina 63-65

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

Ma l'asporto, e si può dire dal IL, è che sono i metodi getter e setter per trattare con gli array alle posizioni dell'indice date.

• Un metodo Get che prende una sequenza di argomenti Int32, uno per ogni dimensione della matrice, e restituisce un valore cui tipo è il tipo di elemento dell'array. Questo metodo viene utilizzato per per accedere a un elemento specifico dell'array dove gli argomenti specificano l'indice in ogni dimensione, a partire da il primo, dell'elemento da restituire .

• un metodo set che prende una sequenza di argomenti Int32, uno per ogni dimensione della matrice, seguita da un valore cui tipo è il tipo di elemento dell'array. Il tipo di reso del Set è nullo.Questo metodo viene utilizzato per impostare un elemento specifico della matrice dove gli argomenti specificano l'indice in ogni dimensione, a partire dalla prima, dell'elemento da impostare e l'ultimo argomento specifica il valore da memorizzare l'elemento obiettivo.

• Un metodo Indirizzo che prende una sequenza di argomenti Int32, uno per ciascun dimensione della matrice, e ha un tipo ritorno che è un puntatore gestito al tipo di elemento della matrice. Questo metodo viene utilizzato per restituire un puntatore gestito ad un elemento specifico dell'array dove gli argomenti specificano l'indice in ogni dimensione, cominciando con il primo, dell'elemento cui indirizzo deve essere restituito.

Edit: di che le pagine 63-65 usando la numerazione delle pagine del documento. 73-75 nel PDF attuale.

+0

Eccellente! Questo è esattamente quello che stavo cercando. Grazie. –

1

Non sono sicuro che risponderà alla tua domanda specifica ma un grande testo sull'argomento (tra gli altri) è CLR via C#. Diventa molto approfondito per molti degli argomenti a cui sei interessato e trascorre molto tempo con il disassemblatore a esaminare il funzionamento interno di molti tipi .NET di base, inclusi gli array. Sicuramente vale la pena dare un'occhiata.

+0

Grazie per avermi ricordato di guardare CLR tramite C#, che ho qui. Ho appena letto il Capitolo 13: Array ma non riesco a vedere alcuna menzione dei metodi Get, Set e Address. –

2

Per rispondere alla seconda domanda, non è necessario creare un'istanza per ottenere uno MethodInfo per questi metodi. Qualcosa di simile

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

lavorerà per ottenere il metodo Get per il tipo di string[,,,,,].

+0

Splendido! Ora ho tutto ciò per cui sono venuto. –

+1

Successivamente ho scoperto che è necessario prestare attenzione quando si seleziona tra gli overload di MakeArrayType. Senza argomenti - MakeArrayType() crea un tipo di vettore come string []. Con un argomento di uno - MakeArrayType (1) crea un array multidimensionale con una dimensione di tipo stringa [*]. Questi tipi non sono compatibili. Per l'interoperabilità con gli altri linguaggi .NET, ciò significa che quando rank == 1 è necessario chiamare caso al metodo parameterless. –

Problemi correlati