Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 842
Mikko Rantanen Avatar asked May 05 '09 21:05

Mikko Rantanen


2 Answers

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).

like image 183
Marc Gravell Avatar answered Oct 14 '22 12:10

Marc Gravell


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.

like image 43
Mikko Rantanen Avatar answered Oct 14 '22 11:10

Mikko Rantanen