Can I improve my .NET COM object to catch usage errors at compile time in VB6

Russ Suter
Russ Suter used Ask the Experts™
on
For some time now I've been writing C# COM visible DLLs for use in an old VB6 application.

I've recently become aware that my COM visible class isn't browsable in the Object Browser nor does the IDE catch compile-time errors. Here's a sample interface and class:
namespace Sample
{
    [Guid("FDB56085-E1C2-41E3-8B6A-86F734B9338B")]
    public interface ITest
    {
        #region Methods

        void Foo();
        void Bar();

        #endregion
    }
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [Guid("6717C7FC-9E3F-47A1-955C-09734F96B18F")]
    public class Test: ITest
    {
        #region Public Methods

        public void Foo()
        {

        }

        public void Bar()
        {

        }

        #endregion
    }
}

Open in new window

All this compiles fine and any code I insert into Foo() or Bar() will execute without a problem. However, I can also do this in VB6:
    Dim tAs Sample.Test
    t.Foo
    t.Bar
    t.CompileError

Open in new window

and the compiler doesn't complain at all. At runtime the last line does generate an error indicating that the method is not implemented but nothing at compile time. Also, the entire class is not browsable in the Object Browser. I can live with the 2nd part but I'm hoping there's a way to force the compiler to catch such errors during compilation. Any suggestions?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Éric MoreauSenior .Net Consultant
Top Expert 2016

Commented:
do you have a reference in VB6 to your COM object? Are you using early or late binding?
Russ SuterSenior Software Developer

Author

Commented:
Specifically, I want to enforce early binding. I actually found a couple of answers but I'm unclear on a minor point.

Solution 1: Don't bother with an interface and add set the ClassInterface attribute of the class like this:
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("6717C7FC-9E3F-47A1-955C-09734F96B18F")]
    public class Test: ITest

Open in new window

However, Microsoft's own documentation recommends not to do this although I'm a bit unclear as to the reasons why. https://docs.microsoft.com/en-us/visualstudio/code-quality/ca1408?view=vs-2019

Solution 2: Set the InterfaceType attribute of the interface like this:
    [Guid("FDB56085-E1C2-41E3-8B6A-86F734B9338B")]
    [InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
    public interface ITest

Open in new window

This doesn't make the object visible in the Object Browser but it does enforce early binding.

Solution 3: Set the InterfaceType attribute of the interface like this:
    [Guid("FDB56085-E1C2-41E3-8B6A-86F734B9338B")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIIUnknown)]
    public interface ITest

Open in new window

For my purposes this has the same effect as solution 2 but there must be a difference. I just can't find any documentation to tell me exactly what that difference actually is.

In any event, right now I'm using solution 3 and letting the VB6 IDE compiler tell me where things are wrong. It's functional and it's getting me  further along. I just wish I knew what the actual difference is between solution #2 and #3.
Senior .Net Consultant
Top Expert 2016
Commented:
it seems that the interface is fooling the VB6 compiler. Add this attribute to your interface:
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)

Open in new window

Have a look at https://stackoverflow.com/questions/25469968/forcing-the-vb6-compiler-to-use-early-binding-when-calling-a-net-com-dll
Russ SuterSenior Software Developer

Author

Commented:
I had already reached that conclusion (see my post above). Thanks though.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial