Russ Suter
asked on
Can I improve my .NET COM object to catch usage errors at compile time in VB6
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:
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
}
}
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
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?
do you have a reference in VB6 to your COM object? Are you using early or late binding?
ASKER
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:
Solution 2: Set the InterfaceType attribute of the interface like this:
Solution 3: Set the InterfaceType attribute of the interface like this:
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.
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
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-2019Solution 2: Set the InterfaceType attribute of the interface like this:
[Guid("FDB56085-E1C2-41E3-8B6A-86F734B9338B")]
[InterfaceType(ComInterfaceType.InterfaceIsIInspectable)]
public interface ITest
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
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
I had already reached that conclusion (see my post above). Thanks though.