Il comportamento del compilatore C#, presentato prima qui da Diego e poi nel mio post precedente, sembra singolare tra gli altri compilatori piu' conosciuti .NET. Il seguente snippet C# entra in stack overflow:
using System;
class Foo {
    public virtual void Write(string s) {
        Console.WriteLine("Foo virtual " + s);
    }
}
class Bar : Foo {
    public override void Write(string s) {
        Console.WriteLine("Bar override " + s);
    }
    public void Write(string s, params string[] args) {
        Write("Bar overload " + s);
    }
}
class Program {
    static void Main() {
        Bar bar = new Bar();
        bar.Write("Ciao!"); // Process is terminated due to StackOverflowException
    }
}
mentre per gli altri linguaggi, stampa Bar override Ciao! Di seguito il codice equivalente in Visual Basic .NET, C++/CLI e Visual J#
Imports System
Class Foo
    Public Overridable Sub Write(ByVal s As String)
        Console.WriteLine("Foo virtual " + s)
    End Sub
End Class
Class Bar : Inherits Foo
    Public Overrides Sub Write(ByVal s As String)
        Console.WriteLine("Bar override " + s)
    End Sub
    Public Overloads Sub Write(ByVal s As String, ParamArray args As String())
        Write("Bar overload " + s)
    End Sub
End Class
Module Program
    Sub Main
        Dim bar As Bar = New Bar
        bar.Write("Ciao") ' stampa Bar override Ciao!
    End Sub
End Module
using namespace System;
ref class Foo {
    public:
    virtual void Write(String^ s) {
        Console::WriteLine("Foo virtual " + s);
    }
};
ref class Bar : Foo {
    public:
    virtual void Write(String^ s) override {
        Console::WriteLine("Bar override " + s);
    }
    void Write(String^ s, ... array<String^>^ args) {
        Write("Bar overload " + s);
    }
};
int main() {
    Bar^ bar = gcnew Bar;
    bar->Write("Ciao!"); // stampa Bar override Ciao!
};
import System.*;
class Foo {
    public void Write(String s) {
        Console.WriteLine("Foo virtual " + s);
    }
}
class Bar extends Foo {
    public void Write(String s) {
        Console.WriteLine("Bar override " + s);
    }
    public void Write(String s, /** @attribute ParamArray() */ String[] args) {
        Write("Bar overload " + s);
    }
}
class Program {
    public static void main(String[] args) {
        Bar bar = new Bar();
        bar.Write("Ciao"); // stampa Bar override Ciao!
    }
}
Ho sempre considerato C# come linguaggio "centrale" di .NET, una chiave per capire meglio lo spirito della piattaforma - percio' mi meraviglio quando trovo comportamenti in C# che sono piuttosto l'eccezione anziche' la regola rispetto agli altri linguaggi .NET. A voi quale comportamento sembra piu' corretto/intuitivo?