Sabato scorso, Stefano ha richiamato sul suo blog il mio post "Main non public?" in cui mi chiedevo "qual è la ragione per cui un metodo Main possa avere qualunque accessibilità...". E' passata una settimana e nessuno ha risposto. Provo allora io a dare una risposta.
Mi sono creato un file Foo.cs:
class Foo
{
static void Main()
{
}
}
Con:
csc Foo.cs
ho ottenuto l'eseguibile Foo.exe. L'ho passato poi a ildasm:
ildasm Foo.exe /out=Foo.il
per ottenere il codice IL:
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 1:0:5000:0
}
.assembly Foo
{
.hash algorithm 0x00008004
.ver 0:0:0:0
}
.module Foo.exe
.imagebase 0x00400000
.subsystem 0x00000003
.file alignment 512
.corflags 0x00000001
.class private auto ansi beforefieldinit Foo extends [mscorlib]System.Object
{
}
.class private auto ansi beforefieldinit Foo extends [mscorlib]System.Object
{
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 0
IL_0000: ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 1
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
}
}
e ho modificato il nome del metodo Main in MyMain. Il file Foo.il così modificato si ricompila con ilasm:
ilasm Foo.il
riottenendo Foo.exe ma con un metodo entrypoint che non si chiama Main. Foo.exe si esegue senza errori.
La morale è che la direttiva IL .entrypoint decora il metodo che "farà da" Main, quindi in .NET il metodo Main ha un ruolo di aspect (se si può dire così). Per questo, forse, l'accessibilità di Main non ha importanza (e neanche significato).
Guardando però la signatura IL del Main, mi sono posto un'altra domanda: che senso ha hidebysig per un metodo Main? (hidebysig vuol dire "hides base class method of exact signature", ma quanti metodi Main avete visto voi nelle classi base?...)