Lorsque les gens parlent du «framework .net», ils ont tendance à combiner deux domaines principaux - la bibliothèque d'exécution et la machine virtuelle qui exécute réellement le code .net.
Lorsque vous créez une bibliothèque de classes dans Visual Studio en C #, la DLL suit un format prescrit - très approximativement, il y a une section qui contient des métadonnées qui décrit les classes qui y sont incluses et quelles fonctions elles ont, etc. et qui décrit où dans le binaire, ces objets existent. Ce format .net commun est ce qui permet aux bibliothèques d'être partagées entre les langages .net (C #, VB.Net, F # et autres) facilement. Bien qu'une grande partie de la «bibliothèque d'exécution» .net soit écrite en C # maintenant (je crois), vous pouvez imaginer combien d'entre elles auraient pu être écrites dans des langues non gérées mais disposées dans ce format prescrit afin qu'elles puissent être consommées par les langues .net .
La véritable "viande" de la bibliothèque que vous créez est constituée de CIL ("Common Intermediate Language") qui est un peu comme le langage d'assemblage de .net - encore une fois, ce langage est la sortie commune de tous les langages .net, ce qui est ce que rend les bibliothèques .net consommables par n'importe quel langage .net.
En utilisant l'outil "ildasm.exe", qui est disponible gratuitement dans les SDK Microsoft (et peut-être déjà sur votre ordinateur), vous pouvez voir comment le code C # est converti en métadonnées et en IL. J'ai inclus un exemple au bas de cette réponse à titre d'exemple.
Lorsque vous exécutez exécuter du code .net, ce qui se passe généralement, c'est que la machine virtuelle .net lit cet IL et le traite. Il s'agit de l'autre côté de .net et, encore une fois, vous pouvez probablement imaginer que cela pourrait facilement être écrit dans un langage non géré - il suffit "de lire" les instructions de la machine virtuelle et de les exécuter (et de l'intégrer au garbage collector, qui a également besoin pas de code .net).
Ce que j'ai décrit est (encore une fois) ce qui se passe lorsque vous créez un exécutable dans Visual Studio (pour plus d'informations, je recommande fortement le livre "CLR via C # par Jeffrey Richter" - il est très détaillé et très bien écrit).
Cependant, il peut arriver que vous écriviez C # qui ne sera pas exécuté dans un environnement .net - par exemple, Bridge.NET "compile" le code C # en JavaScript qui est ensuite exécuté dans le navigateur (l'équipe qui le produit est passée à l'effort d'écrire des versions de la bibliothèque d'exécution .net qui sont écrites en JavaScript et ainsi la puissance et la flexibilité de la bibliothèque .net sont disponibles pour le JavaScript généré). Ceci est un parfait exemple de la séparation entre C # et .net - il est possible d'écrire C # pour différentes "cibles"; vous pouvez cibler l'environnement d'exécution .net (lorsque vous créez un exécutable) ou vous pouvez cibler l'environnement de navigateur (lorsque vous utilisez Bridge.NET).
Un exemple de classe (très) simple:
using System;
namespace Example
{
public class Class1
{
public void SayHello()
{
Console.WriteLine("Hello");
}
}
}
Les métadonnées et IL résultants (récupérés via ildasm.exe):
// Metadata version: v4.0.30319
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}
.assembly Example
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx
63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.
// --- The following custom attribute is added automatically, do not uncomment -------
// .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0A 54 65 73 74 49 4C 44 41 53 4D 00 00 ) // ...TestILDASM..
.custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0A 54 65 73 74 49 4C 44 41 53 4D 00 00 ) // ...TestILDASM..
.custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9 20 // ...Copyright ..
20 32 30 31 36 00 00 ) // 2016..
.custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 )
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 31 39 33 32 61 32 30 65 2D 61 37 36 64 // ..$1932a20e-a76d
2D 34 36 33 35 2D 62 36 38 66 2D 36 63 35 66 36 // -4635-b68f-6c5f6
32 36 36 31 36 37 62 00 00 ) // 266167b..
.custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 ) // ...1.0.0.0..
.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1C 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B // ....NETFramework
2C 56 65 72 73 69 6F 6E 3D 76 34 2E 35 2E 32 01 // ,Version=v4.5.2.
00 54 0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 // .T..FrameworkDis
70 6C 61 79 4E 61 6D 65 14 2E 4E 45 54 20 46 72 // playName..NET Fr
61 6D 65 77 6F 72 6B 20 34 2E 35 2E 32 ) // amework 4.5.2
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module Example.dll
// MVID: {80A91E4C-0994-4773-9B73-2C4977BB1F17}
.imagebase 0x10000000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x05DB0000
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi beforefieldinit Example.Class1
extends [mscorlib]System.Object
{
.method public hidebysig instance void
SayHello() cil managed
{
// Code size 13 (0xd)
.maxstack 8
IL_0000: nop
IL_0001: ldstr "Hello"
IL_0006: call void [mscorlib]System.Console::WriteLine(string)
IL_000b: nop
IL_000c: ret
} // end of method Class1::SayHello
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 8 (0x8)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: nop
IL_0007: ret
} // end of method Class1::.ctor
} // end of class Example.Class1
// =============================================================