Mikko Rantanen
Mikko Rantanen

Reputation: 8084

VB.Net constructor order matters?

Why does constructor ORDER matter in VB.Net? I am building a .Net type library which is meant to wrap an underlying COM library completely so that the consumers of the API can pretend to use a nice .Net library with .Net collections and whatnot instead of a COM library.

Currently most of my classes are just 1 to 1 wrappers built using Reflection and CodeDOM. These classes have an internal constructor which takes the underlying COM type as a parameter. The CodeDOM builds this as the first constructor to the class. Using these classes from C# proves to be no problem. All I need is a reference to the .Net library and all works good.

The problems appear when I try using these classes from a VB.Net project. If the first constructor has a COM type as an argument, the VB.Net project requires the COM interop assembly as a reference. If the first constructor has no arguments or has only managed types all works good. My class library is written in C#.

The following works:

public class ObjectID
{
    public ObjectID(int type, int id)
    {
        this.Type = type;
        this.ID = id;
    }

    internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { }

    public int ID { get; set; }
    public int Type { get; set; }

    internal COMLib.ObjectID ToCOM()
    {
        COMLib.ObjectID id = new COMLib.ObjectID();
        id.ID = this.ID;
        id.Type = this.Type;
        return id;
    }
}

The following requires a reference to the COMLib.Interop assembly:

public class ObjectID
{
    internal ObjectID(COMLib.ObjectID id) : this(id.Type, id.ID) { }

    public ObjectID(int type, int id)
    {
        this.Type = type;
        this.ID = id;
    }

    public int ID { get; set; }
    public int Type { get; set; }

    internal COMLib.ObjectID ToCOM()
    {
        COMLib.ObjectID id = new COMLib.ObjectID();
        id.ID = this.ID;
        id.Type = this.Type;
        return id;
    }
}

Now I can solve this by creating a dummy private constructor to these classes as the first constructor but I'm more curious about what causes this? Why does the order of the constructor declarations matter in VB.Net?

Update

This sounded so insane that I started doubting it myself. Managed to replicate it with 3 projects.

C# Class library: Wrapped

namespace Wrapped
{
    public class Class1
    {
    }
}

C# Class library: Wrapper

namespace Wrapper
{
    public class Class1
    {
        internal Class1(Wrapped.Class1 c) { }
        public Class1() { }
    }
}

VB.Net Console app: Referer

Module Module1
    Sub Main()
        Dim w As New Wrapper.Class1
    End Sub
End Module

Wrapper refers to Wrapped Referer refers to Wrapper Referer does NOT refer to Wrapped

Dim w As New Wrapper.Class1

Produces an error

Reference required to assembly 'Wrapped, Version=1.0.0.0,
                                         Culture=neutral,
                                         PublicKeyToken=null'
containing the type 'Wrapped.Class1'.
Add one to your project.

Swapping the order of constructors takes care of the error.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=442224

Update after playing around some more

Causes error:          No error:

     Vb-ReferTest          Vb-RefererTest
          |                      |                     Fixes error in Vb-
          V                      V                      RefererTest even
      Cs-Wrapper            Cs-Wrapper   Vb-Wrapper <-  if the Vb-Wrapper
          |                       \         /          and the RefererTest
          V                        V       V             have no direct
   Cs-WrappedLibrary           Cs-WrappedLibrary          relationship

Upvotes: 8

Views: 1490

Answers (3)

Mikko Rantanen
Mikko Rantanen

Reputation: 8084

Confirmed as a bug. Too difficult to fix for it to be worth it too, so I guess we'll just live with it. Fortunately it seems to require cross language projects with uncommon class setups to crop up.

Upvotes: 1

Chris Pietschmann
Chris Pietschmann

Reputation: 29905

No, the order of your Constructors as they are listed in code (using either C# or VB.NET) does not matter.

However, in this specific case (I have not tested it) you may have found a bug. Before jumping to the "it breaks on my machine" conclusion, you may want to have someone else verify the issue on their machine, so you know it's not just your machine. I've had this happen before.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1063609

If correct (I can't easily verify), that is fasinating. The order shouldn't matter, AFAIK. If you are sure about it, then perhaps log as a bug on connect (with sample code).

Upvotes: 1

Related Questions