COM服务器如何在具有不同ComInterfaceType枚举的C#类库中封送nullable?

COM服务器如何在具有不同ComInterfaceType枚举的C#类库中封送nullable?,c#,.net,vba,excel,com,C#,.net,Vba,Excel,Com,我听说Nullable是一个C#泛型类,它不像其他泛型类那样与COM一起工作 嗯,在我的C#class库中,我有: [InterfaceType(ComInterfaceType.InterfaceIsDual), Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")] public interface ICOMClass { int? GetNullable(); } [ClassInterface(ClassInterfaceType.None)

我听说
Nullable
是一个C#泛型类,它不像其他泛型类那样与COM一起工作

嗯,在我的C#class库中,我有:

[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;
    }
}
令人惊讶的是,它可以编译,并且我能够在VBE中将引用附加到我的
COMClass
库中

我知道:

  • VBA不在对象浏览器的成员列表中列出
    .GetNullable()
    (即使勾选了“显示隐藏成员”)
  • VBA不在intelli sense下拉列表中列出
    .GetNullable()
但为什么:

Dim c as new COMClass
c.GetNullable
是否不抛出预期的
对象不支持此属性或方法

与之相反:

c.NonExistingMethod
有人能解释一下原因吗?

我怀疑这与我的行为有关,因为

  • 两者:
    InterfaceIsDual
    InterfaceIsIDispatch
    的行为与我上面描述的一样
但是:

  • interfaceeisiunknown
    实际上似乎没有封送/触动
    GetNullable()
    并引发预期的错误

有人能解释这种行为吗?

好吧,它是编译的。但您知道,在尝试为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'
您可以通过在类型库上运行OleView.exe来查看它。这是您的界面的外观:

[
  odl,
  uuid(2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E),
  version(1.0),
  dual,
  oleautomation,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "ICOMClass")

]
interface ICOMClass : IDispatch {
};
没什么,娜达,齐波。Microsoft程序员有时在编写诊断消息时过于友好。这不仅仅是“可能不会”,而是“不会”


这是行不通的。它可以通过后期绑定找到方法也没有帮助,返回值无法正确解释,
Nullable
不是[ComVisible]。作为另一种选择,考虑到COM总是有“空性”的概念,在VBA中得到了强有力的支持,这在很大程度上取决于它。变量可以存储vtNull或vtEmpty以指示未设置值。它是C#代码中的对象。

看看这篇文章,搜索一下
[使用可为空的参数]
当你在页面上时,它会更详细地解释。@DJKRAZE非常感谢你的链接,但是我没有找到我的问题的解释:为什么VBA允许调用COM库中任何地方都看不到的方法?我是这个库的开发人员,所以我知道它存在,我发现VBA允许我调用
c.GetNullable()
-我只是问为什么?为什么它没有完全隐藏等等?当您在OLE视图中查看库时,是否有任何迹象表明.tlb/.dll/无论什么都在IDL中隐藏了GetNullable?@Mike我没有看到它(
GetNullable()
)查看类型库时,在OleView中的任何位置…它显然不存在于.tlb文件中,但如果有任何意义,可以直接从.dll访问它。啊哈!由于
.tlb
中不存在该方法,因此仍然不太理解它实际上是如何找到该方法的。
.tlb
仅负责intelli sense和对象浏览器信息,并且直接访问
.dll
是真的吗?例如,当您添加对本机.NET
.dll
的引用时,您在对象浏览器或intelli sense中看不到某些方法,但您仍然可以调用(并失败)某些成员,因为您熟悉API,所以知道它们存在。VBA使用后期绑定作为回退,请注意您的接口如何实现IDispatch。CLR中的一点缺陷可能是故意的。此外,我还没有看到警告,因为VS没有为我弹出错误窗口,我也没有检查警告(是的,我知道我的错!!)。