我用 C# 4.0 编写了一个 COM 可见的类库,我正在使用 VB6。这件事有效,只有当我打开 VB6 对象浏览器 并查看公开的成员时,我看到每个公开的成员都有一个事件...但 C# 代码没有定义它们中的任何一个。
这正常吗?我做错了什么吗?
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(IMyClass))]
public class MyClass : IMyClass
{
public void DoSomething(string someParam)
{
...
}
}
public interface IMyClass
{
void DoSomething(string someParam);
}
程序集使用强名称 key 进行签名,并且 AssemblyInfo.cs
具有 [assembly: ComVisible(true)]
属性集,但我不确定与这个问题有任何关系。
当我查看 VB6 中的对象浏览器时,我希望看到 DoSomething(string)
作为 MyClass
的成员,我确实看到了,但是我也看到一个事件,每个公开的方法都有一个匹配的签名,比如 Event DoSomething(someParam As String)
作为 的成员我的类(class)
。
更令人费解的是(至少对我而言),属性也有一个“匹配”事件(虽然只能从小闪电图标看出)——如果 MyClass
定义了这样的属性:
public string SomeProperty { get; set; }
VB6 对象浏览器会说“事件”被定义为 Property SomeProperty As String
,这让我大吃一惊 - “属性”如何 1) 被复制和 2) 显示重复项在对象浏览器中带有“事件”图标?这同样适用于只读属性,它们有只读的“属性/事件”对应物。
这些事件从何而来,我该如何摆脱它们?
更新一张图片胜过一千个字:
更新 错误 是 ComSourceInterfaces
属性被错误地用于代替 ComDefaultInterface
属性.将前者换成后者会得到预期的结果:
最佳答案
通过将 typeof(IMyClass)
作为参数传递给 ComSourceInterface 属性,您表示 IMyClass 中的所有内容都是一个事件。
如果您不想为您的类使用事件接口(interface),请移除 ComSourceInterface 属性。
如果您确实想要将 C# 类中的事件公开给 VB,请执行以下操作:
当您创建一个 COM 可见类时,您还需要创建一个接口(interface),该接口(interface)只为您的类定义事件处理程序。您的类应该使用指定事件处理程序接口(interface)的 COMSourceInterface 进行修饰,并且应该定义您的事件并实现事件处理程序接口(interface)。参见 How To: Raise Events Handled by a COM sink再举个例子。
[GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967") ]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface MyEvents
{
void ConnectedEvent(string state);
}
[ComSourceInterfaces(typeof(MyEvents))]
public class MyClass
{
public event Action<string> ConnectedEvent;
public MyClass() { }
public void DoSomething(string state)
{
if (ConnectedEvent != null)
ConnectedEvent(state);
}
}
关于c# - VB6/COM 互操作 : where do these events come from?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16600023/