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

Overloading non-generic virtual methods in generic classes (C# vs VB.NET)

Ho  notato un comportamento diverso (C# vs VB.NET) per l'overloading di metodi virtuali non-generici in classi generiche e, come notava il buon Raffaele in una discussione sul messenger "la regola di scegliere l'una o l'altra non è dettata dal CLS e qui scoppiano i problemi quando traduci un listato - un bel pasticcio". Lo snippet C# sotto:

using System;
 
class Foo {
     public virtual void DoSomething(object o) {
          Console.WriteLine("void Foo::DoSomething(object)");
     }
}
 
class Bar<T> : Foo {
     public void DoSomething(T t) {
          Console.WriteLine("void Bar<T>::DoSomething(T)");
     }
 
     public override void DoSomething(object o) {
          Console.WriteLine("void Bar<T>::DoSomething(object)");
     }
}
 
class Baz : Foo {
     public override void DoSomething(object o) {
          Console.WriteLine("void Baz::DoSomething(object)");
     }
}
 
class Test {
     static void Main() {
          Bar<object> bar = new Bar<object>();
          Baz baz = new Baz();
          bar.DoSomething(new object());
          baz.DoSomething(new object());
     }
}

stampa a console:

void Bar<T>::DoSomething(T)
void Baz::DoSomething(object)

mentre l'equivalente VB.NET:

Imports System
 
Class Foo
    Public Overridable Sub DoSomething(ByVal o As Object)
        Console.WriteLine("void Foo::DoSomething(object)")
    End Sub
End Class
 
Class Bar(Of T) : Inherits Foo
    Public Overloads Sub DoSomething(ByVal t As T)
        Console.WriteLine("void Bar<T>::DoSomething(T)")
    End Sub
 
    Public Overrides Sub DoSomething(ByVal o As Object)
        Console.WriteLine("void Bar<T>::DoSomething(object)")
    End Sub
End Class
 
Class Baz : Inherits Foo
    Public Overrides Sub DoSomething(ByVal o As Object)
        Console.WriteLine("void Baz::DoSomething(object)")
    End Sub
End Class
 
 
Module Test
    Sub Main()
        Dim bar As Bar(Of Object) = New Bar(Of Object)
        Dim baz As Baz = New Baz
        bar.DoSomething(New Object)
        baz.DoSomething(New Object)
    End Sub
End Module

stampa a console:

void Bar<T>::DoSomething(object)
void Baz::DoSomething(object)

Quando invece in C# istanziamo in questo modo:

Foo bar = new Bar<object>();
Foo baz = new Baz();

otteniamo il comportamento di VB.NET. Sinceramente all'inizio ero tentato di dare ragione a VB.NET, però in effetti Raf mi ha convinto del fatto che, in questo ultimo snippet C# (questo subito sopra) noi chiediamo esplicitamente al compilatore un comportamento polimorfico mentre nei due snipet C# e VB.NET a confronto il comportamento polimorfico è soltanto implicito e quindi, potendo scegliere, il compilatore C# chiama "quella più tipizzata". Nel caso di baz, "non hai alternative, c'è solo quella e la usa sempre". E' vero.

Magari Corrado potrebbe postare sulla mailing list di VB.NET il domandone a Paul Vick? Sarebbe interessante sapere le motivazioni che hanno determinato il team VB.NET di fare questa scelta.

Print | posted on sabato 21 ottobre 2006 15:54 | Filed Under [ Carillon .NET ]

Powered by:
Powered By Subtext Powered By ASP.NET