Pergunta

Estou tentando entender um método usando o recurso de desmontagem do refletor. Como qualquer pessoa que seja usada essa ferramenta saberá, certos código são exibidos com etiquetas C# que foram (presumivelmente) não usadas na fonte original.

No método de 110 linhas que estou vendo, existem 11 declarações de etiquetas. Exemplos aleatórios de snippet:

Label_0076:
    if (enumerator.MoveNext())
    {
        goto Label_008F;
    }
    if (!base.IsValid)
    {
        return;
    }
    goto Label_0219;
Label_0087:
    num = 0;
    goto Label_01CB;
Label_01CB:
    if (num < entityArray.Length)
    {
        goto Label_0194;
    }
    goto Label_01AE;
Label_01F3:
    num++;
    goto Label_01CB;

Que tipo de código faz com que o refletor exiba esses rótulos em todos os lugares e por que não pode desmontá -los?

Existe uma boa técnica para decifrá -los?

Foi útil?

Solução

Você está olhando para o código gerado pelo compilador. O compilador não o respeita. Não mesmo. Isso também não me respeita ou mais ninguém. Ele analisa nosso código, zomba de nós e o reescreve para executar da maneira mais eficiente possível.

Aninhadas se declarações, recursão, "rendimento" s, declarações de caso e outros atalhos de código resultarão em código de aparência estranha. E se você estiver usando lambdas com muitos gabinetes, bem, não espere que seja bonito.

Em qualquer lugar, qualquer chance de o compilador reescrever seu código para fazê -lo funcionar mais rapidamente. Portanto, não há um "tipo de código" que causará isso. O Reflector faz o possível para desmontar, mas não pode adivinhar o código original do autor de sua versão reescrita. Faz o seu melhor (que às vezes está incorreto!) Para traduzir IL em alguma forma de código aceitável.

Se você está tendo dificuldade em decifrá -lo, poderá editar manualmente o código para inline o Goto que só é chamado uma vez e refator os Goto's que são chamados mais de uma vez em chamadas de método. Outra alternativa é desmontar em outro idioma. O código que traduz IL em idiomas de nível superior não é o mesmo. O decompilador C ++/CLI pode fazer um trabalho melhor para você e ainda ser semelhante o suficiente (encontre/substitua -> com.) Para ser compreensível.

Realmente não há uma bala de prata para isso; Pelo menos até que alguém escreve um plugin de desmontador melhor.

Outras dicas

Na verdade, o compilador C# não faz muita otimização - deixa isso para o compilador JIT (ou NGEN). Como tal, o IL que gera é bastante consistente e previsível, e é por isso que ferramentas como o refletor são capazes de descompilar o IL de maneira tão eficaz. Uma situação em que o compilador transforma seu código está em um iterador método. O método que você está olhando provavelmente continha algo como:

foreach(var x in something)
  if(x.IsValid)
    yield return x;

Como a transformação do iterador pode ser bastante complexa, o refletor não pode realmente lidar com isso. Para se familiarizar com o que procurar, escreva seus próprios métodos de iterador e execute -os através do refletor para ver que tipo de IL é gerado com base no seu código C#. Então você saberá o que procurar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top