Ho finalmente scoperto come mai le applicazioni VB.NET si portano appresso la fantomatica Microsoft.VisualBasic.dll, infatti analizzando il manifest di un applicazione VB.NET si nota sempre la presenza di

.assembly extern Microsoft.VisualBasic
{
  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:
  .ver 7:0:5000:0
}

Questo e' dovuto al fatto che il codice IL non e' in grado di supportare tutte le funzionalita' messe a disposizione da VB, infatti se si 'boxa' un Int, IL permette di "unboxarlo" esclusivamente a un Int, quindi per fare giochetti tipo

 Dim i As Int32 = 1
 Dim o As Object = i
 Dim f As Single = CType(o,Single)

Il codice IL corrispondente e':

{
  // Code size       19 (0x13)
  .maxstack  1
  .locals init ([0] float32 f,
           [1] int32 i,
           [2] object o)
  IL_0000:  nop
  IL_0001:  ldc.i4.1
  IL_0002:  stloc.1
  IL_0003:  ldloc.1
  IL_0004:  box        [mscorlib]System.Int32
  IL_0009:  stloc.2
  IL_000a:  ldloc.2
  IL_000b:  call       float32 [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.SingleType::FromObject(object)
  IL_0010:  stloc.0
  IL_0011:  nop
  IL_0012:  ret
}

Infatti l'equivalente C# (piu' IL tied) non compila

Int32 i=1;
object o=i;
float f=(float)o; // Error

Infatti il relativo IL e'

{
  // Code size       18 (0x12)
  .maxstack  1
  .locals init ([0] int32 i,
           [1] object o,
           [2] float32 f)
  IL_0000:  ldc.i4.1
  IL_0001:  stloc.0
  IL_0002:  ldloc.0
  IL_0003:  box        [mscorlib]System.Int32
  IL_0008:  stloc.1
  IL_0009:  ldloc.1
  IL_000a:  unbox      [mscorlib]System.Single
  IL_000f:  ldind.r4
  IL_0010:  stloc.2
  IL_0011:  ret
}

Dove e' evidente il tentativo di unboxing verso un Single (divertente notare che C# lo chiama comunque float...)

mentre, per ovvi motivi, compila se l'ultima riga e' Int32 f=(Int32)o;

La parte interessante e' che la helper library e' stata scritta in VB.NET...

Ok, ora e' forse meglio che vada a dormire...