I hear that Nullable<T>
is a C# generic class and it does not work with COM - like any other generic class.
Well, in my C# class library I have:
[InterfaceType(ComInterfaceType.InterfaceIsDual),
Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")]
public interface ICOMClass
{
int? GetNullable();
}
[ClassInterface(ClassInterfaceType.None)]
[Guid("57BBEC44-C6E6-4E14-989A-B6DB7CF6FBEB")]
public class COMClass : ICOMClass
{
public int? GetNullable()
{
int? hello = null;
return hello;
}
}
Surprisingly that compiles and I am able to attach references to my COMClass
library in VBE.
I know that:
- VBA does not list
.GetNullable()
in the list of members on Object Browser (even with show hidden members ticked)
- VBA does not list
.GetNullable()
in the intelli-sense drop down
but why:
Dim c as new COMClass
c.GetNullable
does not throw a rather expected Object doesn't support this property or method
?
as opposed to:
c.NonExistingMethod
Can anyone explain why?
I am suspicious that it has something to do with ComInterfaceType
Enumeration because
- both:
InterfaceIsDual
& InterfaceIsIDispatch
act just like I described above
but:
InterfaceIsIUnknown
actually doesn't seem to marshal/touch the GetNullable()
and the expected error is thrown...
Can anyone explain this behaviour?
Well, it compiles. But you know you got trouble when you try to create a type library for the DLL:
C:\projects2\ClassLibrary38\bin\Debug>tlbexp ClassLibrary38.dll
Microsoft (R) .NET Framework Assembly to Type Library Converter 4.0.30319.33440
Copyright (C) Microsoft Corporation. All rights reserved.
TlbExp : warning TX8013117D : Type library exporter warning processing 'ICOMClas
s.GetNullable(#0), ClassLibrary38'. Warning: Type library exporter encountered a
generic type instance in a signature. Generic code may not be exported to COM.
Assembly exported to 'C:\projects2\ClassLibrary38\bin\Debug\ClassLibrary38.tlb'
You can look at it by running OleView.exe on the type library. This is what your interface looks like:
[
odl,
uuid(2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E),
version(1.0),
dual,
oleautomation,
custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "ICOMClass")
]
interface ICOMClass : IDispatch {
};
Nothing, nada, zippo. Microsoft programmers sometimes are too friendly when they write diagnostic message. It is not just "may not be", it is "will not be".
This is not going to work. That it can find the method by late binding won't help, the return value cannot be interpreted properly, Nullable<T>
is not [ComVisible]. As an alternative, consider that COM always had to notion of "nullability", strongly supported in VBA which depends on it a great deal. Variants can store vtNull or vtEmpty to indicate that a value is not set. It is object in C# code.