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.