Here's a (big, bad) difference between VB.NET and C#

Ricardo blogs about the differences between C# and VB.NET. Well, I'll give you one, which is very harmful in some areas.

Class C is a derived class from DataTable. DataTable implements ISerializable, but does this private. Class C has a new member variable which has to be serialized as well. Simply adding '[Serializable]' to Class C doesn't work, because a base class already implements ISerializable. So C has to implement ISerializable too.

Because DataTable implements ISerializable private (ISerializable.GetObjectData() is private), this can be a problem, since I have to do the complete serialization of C and the data in its base class by hand. Dino Esposito wrote an article about that, it's located here.

Using Dino's article, I can implement ISerializable and the GetObjectData() code to serialize the data and the private membervariable of C. That is... in C#. In VB.NET you can't, because the VB.NET compiler will throw an error that a base class of C already implements ISerializable. There is no way in VB.NET to re-implement ISerializable or to make the serialization formatter call a GetObjectData() method defined in C to do the serialization, simply because it will see the GetObjectData() method of DataTable as the implementation of ISerializable.GetObjectData(), which will serialize the DataTable contents, but not private member variables of derived classes.

Now, it took me some time to work around this (create a C# class with the member variable, derive the VB.NET class from that class) and it still isn't a solution which will work in all cases. In other words: VB.NET lacks re-implementation of interface members and with classes like DataTable in .NET (some winforms controls also have some interface members implemented privately, so you can't re-implement them) which have a privately implemented ISerializable, VB.NET can be a struggle in some situations, so be careful which language to pick for some of your classes.

11 Comments

  • You don't have to look THAT far to find crippling differences - lack of C variable types (such as unsigned bytes, words etc) makes VB.NET totally unusable for many low level scenarios such as encyption, hashing, CRC algorithms, etc.



  • This might sound stupid, but how would you go about doing private implementation of an interface? Did you mean not declaring the interface name in the class declaration and just writing out the methods of the interface as regular methods?

  • Well, my guess is that sort of thing would just make Mort's head hurt, so it has no place in VB.



    As far ass private implementations:



    interface IFoo { void Bar(); }



    class X: IFoo

    {

    void IFoo.Bar() { }

    }



    elsewhere, you can't do this:

    X x = new X();

    x.Bar(); // not allowed



    but you can do this:

    IFoo f = x;

    f.Bar();

  • ROFL: make that as, not ass

  • Micky, Thanks. BTW, I'm a Mort :) My head isn't hurting one bit, but my pride is a little.

  • Can't you use shadowing to resolve this issue?

    Use the Shadows keyword on the GetObjectData() method. From the Visual Basic Language Reference: "If the shadowing element is not accessible from the code referring to it, for example if it is Private, the reference is resolved to the shadowed element."

  • Sander: No, because you have to specify Implements ISerializable with the class, which is not allowed. :)



    Mickey: indeed, that's they way you can do it in C#, and that's the way MS did implement ISerializable on DataTable. Of course that's a bad way to design a class, nevertheless, VB.NET can't 'fix' that, only C# can.

  • C# lets you define a new GetObjectData method, but you still can't call the original method. So you still need to recode the base class implementation. e.g.:



    public class MyTable : DataTable, ISerializable

    {

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)

    {

    ((ISerializable)this).GetObjectData(info, context); // calls this method, not the base class

    ((ISerializable)base).GetObjectData(info, context); // compiler error

    base.GetObjectData(info, context); // compiler error

    }

    }

  • This should work, right?



    public interface Base

    {

    void foo();

    }



    public class Derived1 : Base

    {

    void Base.foo()

    {

    Console.WriteLine("Derived1");

    }

    }



    public class Derived2: Derived1

    {

    public void foo()

    {

    Base b = (Base)base.MemberwiseClone();

    b.foo();

    Console.WriteLine("Derived2");

    }



    }



    So, wouldn't this be easier?(Kindly correct me if I've misunderstood s'thing)

  • Geez. I forgot its VB.Net counterpart! Here it is:



    Interface Base

    Sub Foo()

    End Interface



    Class Derived1

    Implements Base



    Private Sub Foo() Implements Base.Foo

    Console.WriteLine("Derived1")

    End Sub

    End Class



    Class Derived2

    Inherits Derived1





    Public Sub Foo()

    Dim x As Base

    x = Me

    x.Foo()

    Console.WriteLine("Derived2")

    End Sub

    End Class





    And you can test the code with a Module:



    Module Module1



    Sub Main()

    Dim x As New Derived2

    Dim i As Base

    i = x

    i.Foo()

    x.Foo()

    Console.ReadLine()

    End Sub



    End Module

  • And well...there's so many good things about C# here that am compelled to ask if there's any equivalent of the MyClass keyword of VB .Net in C#.



    Thanks

    Krishnan

Comments have been disabled for this content.