Onde posso encontrar informações sobre os métodos GET, Set and Environ para o sistema multidimensional.
-
23-09-2019 - |
Pergunta
System.array Serve como classe base para todas as matrizes no tempo de execução do idioma comum (CLR). De acordo com Este artigo:
Para cada tipo de matriz de concreto, [o] tempo de execução adiciona três métodos especiais:
Get
/Set
/Address
.
E, de fato, se eu desmontar este código 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]);
em CIL eu entendo,
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)
onde as chamadas para o acima mencionado Get
e Set
métodos podem ser vistos claramente. Parece que a arity desses métodos está relacionada à dimensionalidade da matriz, que é presumivelmente por isso que eles são criados pelo tempo de execução e não são pré-declarados. Não consegui localizar nenhuma informação sobre esses métodos no MSDN e seus nomes simples os tornam resistentes ao Google. Estou escrevendo um compilador para um idioma que suporta matrizes multidimensionais, por isso gostaria de encontrar alguma documentação oficial sobre esses métodos, sob quais condições posso esperar que existam e o que posso esperar que sejam suas assinaturas.
Em particular, eu gostaria de saber se é possível obter um MethodInfo
objeto para Get
ou Set
para usar com Reflection.Emit
sem ter que criar um instância da matriz com tipo correto e dimensionalidade sobre a qual refletir, como é feito no exemplo vinculado.
Solução
Olhe aqui, especificamente a Seção 14.2 nas páginas 63-65
Mas o argumento e você pode dizer pela IL, é que eles são os métodos Getter e Setter para lidar com matrizes nas posições de índice fornecidas.
• Um método GET que pega uma sequência de argumentos int32, um para cada dimensão da matriz, e retorna um valor cujo tipo é o tipo de elemento da matriz. Este método é usado para acessar um elemento específico da matriz em que os argumentos especificam o índice em cada dimensão, começando com o primeiro, do elemento a ser retornado.
• Um método de conjunto que pega uma sequência de argumentos int32, um para cada dimensão da matriz, seguida por um valor cujo tipo é o tipo de elemento da matriz. O tipo de retorno de conjunto é nulo. Esse método é usado para definir um elemento específico da matriz em que os argumentos especificam o índice em cada dimensão, começando com o primeiro, do elemento a ser definido e o argumento final especifica o valor a ser armazenado no elemento de destino.
• Um método de endereço que pega uma sequência de argumentos int32, um para cada dimensão da matriz, e possui um tipo de retorno que é um ponteiro gerenciado para o tipo de elemento da matriz. Esse método é usado para retornar um ponteiro gerenciado a um elemento específico da matriz, onde os argumentos especificam o índice em cada dimensão, começando com o primeiro, do elemento cujo endereço deve ser retornado.
Editar: São as páginas 63-65 usando a numeração da página do documento. 73-75 no pdf real.
Outras dicas
Para responder à sua segunda pergunta, você não precisa criar uma instância para obter um MethodInfo
Para esses métodos. Algo como
var mi = typeof(string).MakeArrayType(6).GetMethod("Get");
trabalhará para obter o Get
Método para o string[,,,,,]
modelo.
Não tenho certeza se isso abordará sua pergunta muito específica, mas um ótimo texto sobre o assunto (entre outros) é CLR via C#. Fica muito profundo para muitos dos tópicos em que você está interessado e passa muito tempo com o desmontador olhando para o funcionamento interno de muitos tipos de base .NET, incluindo matrizes. Definitivamente vale a pena conferir.