2009-08-05 6 views
4

Nehmen wir an, Sie schreiben eine App in C#, VB, alles mit .NET Wenn Sie auf Build klicken, kompiliert es wirklich Ihren Code? Das dachte ich, bis ich anfing, Redgates-Reflektoren auf einigen meiner Assemblys zu verwenden und meinen Code wörtlich zu sehen. Ich hätte erwartet, dass Schleifen abgerollt werden und eine weitere Fülle von Optimierungen statt nichts.Wie und wann kompiliert .NET tatsächlich Code?

Wann passiert eigentlich die Kompilierung? Ich denke, wenn es gebaut wird, wird Code IL (Intermediary Language) und wenn die Ausführung stattfindet, wird es in der CLR geladen? Wird es nur während der CLR und niemals während der Erstellung optimiert?

+0

bereits hier beantwortet: http://stackoverflow.com/questions/601974/clr-vs-jit/602010 # 602010 –

+0

@Jorge Ich bin mir nicht sicher, ob das ein genaues Duplikat ist. Ich denke, diese Frage berührt einige der gleichen Probleme, wird aber durch die Frage "Warum sehe ich meinen eigenen Code in Reflector?" Wirklich angespornt. –

+0

@Rex können Sie auf diese Frage verlinken? Ich suchte die Website und google dafür, aber lande nur hier. Vielen Dank. – Matt

Antwort

16

Wenn Sie in VS kompilieren

  1. Ihr Quellcode wird in einen Bytecode kompiliert als gemeinsame Zwischensprache (CIL) oder MSIL bekannt (Microsoft Intermediate Sprache).
  2. Metadaten aus jeder Klasse und jeder Methode (und jede andere Sache: O) ist im PE-Header der resultierenden ausführbaren Datei enthalten (sei es eine DLL oder eine EXE).
  3. Wenn Sie eine ausführbare Datei erstellen, enthält der PE-Header auch einen herkömmlichen Bootstrapper, der beim Ausführen Ihrer ausführbaren Datei für das Laden der CLR (Common Language Runtime) zuständig ist.

Wenn Sie ausführen:

  1. Der bootstraper initialisiert die CLR (vor allem durch die mscorlib Montage Laden) und weist sie an die Assembly auszuführen.
  2. Die CLR führt Ihren Haupteintrag aus.
  3. Klassen haben nun eine Vektortabelle, die die Adressen der Methodenfunktionen enthält, so dass beim Aufruf von MyMethod diese Tabelle durchsucht wird und dann ein entsprechender Aufruf an die Adresse erfolgt. Beim Start haben ALLE Einträge für alle Tabellen die Adresse des JIT-Compilers.
  4. Wenn ein Aufruf einer solchen Methode erfolgt, wird der JIT anstelle der tatsächlichen Methode aufgerufen und übernimmt die Kontrolle. Der JIT kompiliert dann den CIL-Code in tatsächlichen Assemblercode für die geeignete Architektur.
  5. Sobald der Code kompiliert ist, geht das JIT in die Methodenvektortabelle und ersetzt die Adresse durch die des kompilierten Codes, so dass jeder nachfolgende Aufruf das JIT nicht mehr aufruft.
  6. Schließlich behandelt das JIT die Ausführung mit dem kompilierten Code.
  7. Wenn Sie eine andere Methode aufrufen, die noch nicht kompiliert wurde, gehen Sie zurück zu 4 ... und so weiter ...

poste ich die Antwort auch hier als die andere Frage über diese nicht wirklich war ...

+0

Sehr schön beantwortet !!! Danke vielmals !! –

3

Es ist kompiliert zu IL, nun, Kompilierzeit. Die Magie von Reflector ist, dass es die IL "versteht" und sie zurück in C# (oder VB.NET oder was auch immer konvertiert. Unter Reflektoren im Menü "Optionen" können Sie die Assembly in einem beliebigen Format einschließlich der IL anzeigen).

In Reflector sehen Sie nicht Ihren ursprünglichen Code. Sie sehen eine Übersetzung der IL in C#. Die meiste Zeit, die sehr ähnlich sein wird, was Sie geschrieben haben, aber es gibt einige verräterische Zeichen - zum Beispiel, einen Platz finden, wo Sie eine auto-property implementiert:

string MyProperty {get;set;} 

Und Sie werden sehen, was das kompiliert tatsächlich ist das etwa so:

public string MyProperty 
{ 
    [CompilerGenerated] 
    get 
    { 
     return this.<MyProperty>k__BackingField; 
    } 
    [CompilerGenerated] 
    set 
    { 
     this.<MyProperty>k__BackingField = value; 
    } 
}