Web Log di Adrian Florea

"You know you've achieved perfection in design, not when you have nothing more to add, but when you have nothing more to take away." Antoine de Saint-Exupery
posts - 440, comments - 2715, trackbacks - 3944

My Links

Archives

Post Categories

Image Galleries

.RO Blogs

.RO People

.RO Sites

Blogs

Furls

Links

vinCitori

standard module & StandardModule

Nel capitolo 7.7 delle specifiche VB .NET, si può leggere:

"A standard module is a type whose members are implicitly Shared and scoped to the declaration space of the standard module's containing namespace, rather than just to the standard module declaration itself. Standard modules may never be instantiated. It is an error to declare a variable of a standard module type."

ed è vero: provando a istanziare uno standard module in VB .NET si ottiene l'errore BC30371 ("Module '' cannot be used as a type"). Ma come traduce il compilatore di VB .NET in IL uno standard module? Per esempio, a questo codice:

Public Module Foo
  Public Sub DoSomething()
    System.Console.WriteLine("Ciao!")
  End Sub
End
Module

corrisponde in IL la seguente definizione di una classe Foo:

.class public auto ansi sealed Foo extends [mscorlib]System.Object
{
  .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) 
  .method public static void DoSomething() cil managed
  {
    // ...
  }
}

cioè in IL, com'era da aspettarsi, non esiste il concetto di standard module ma, il compilatore VB .NET lo implementa con una classe sealed con tutti i metodi static e decorata coll'attributo Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute. Come se avessimo in C#:

using System;
using Microsoft.VisualBasic.CompilerServices;

[StandardModule]
public sealed class Foo
{
  private Foo(){}
  public static void DoSomething()
  {
    Console.WriteLine("Ciao!");
  }
}

La definizione in IL della classe Foo qui sopra è:

.class public auto ansi sealed beforefieldinit Foo extends [mscorlib]System.Object
{
  .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) 
  .method public hidebysig static void DoSomething() cil managed
  {
    // ...
  }

  .method private hidebysig specialname rtspecialname instance void .ctor() cil managed
  {
    // ...
  }
}

L'unica cosa "in più" rispetto al codice corrispondente allo standard module è il costruttore private. Senza esso il compilatore C# ne avrebbe generato uno di default, public (in discordanza con la definizione dello standard module). Vista la mancanza di un costruttore nel codice IL generato dal compilatore VB .NET per uno standard module, ho provato a istanziare da C# uno standard module scritto in VB .NET:

class Test
{
  static void Main()
  {
    Foo f = new Foo();
  }
}

e sono riuscito :-) La spiegazione è che il compilatore VB .NET riconosce uno standard module in base all'attributo StandardModuleAttribute e quindi "non ha bisogno" di un costruttore private.

Facciamo adesso la strada inversa provando a istanziare da VB .NET:

Class Test
  Shared Sub Main()
    Dim f As Foo = New Foo
  End Sub
End
Class

una classe Foo con il costruttore public:

using System;
using Microsoft.VisualBasic.CompilerServices;

[StandardModule]
public sealed class Foo
{
  public Foo(){}
  public static void DoSomething()
  {
    Console.WriteLine("Ciao!");
  }
}

Sorpresi del fatto che otteniamo l'errore BC30371 ("Module 'Foo' cannot be used as a type.")? Un po' strano, vero? Una classe C# (ma non importa il linguaggio) con costruttore public che non può essere istanziata in VB .NET!

Print | posted on domenica 13 febbraio 2005 16:47 | Filed Under [ Carillon .NET ]

Powered by:
Powered By Subtext Powered By ASP.NET