在VBA中错误地暴露的.NET类型

时间:2011-12-12 15:17:32

标签: .net vba com interop

我试图理解VBA中这种奇怪的行为。我有两个.NET类,它继承接口并暴露给COM。我注册了COM互操作,在VBA中我遇到了这种奇怪的行为,其中对象显示来自错误接口的类型。在代码中解释如下:

C#Class:

namespace ComTest
{
    [ComDefaultInterface(typeof(ITestClass))]
    [ClassInterface(ClassInterfaceType.None)]
    public class TestClass : ITestClass
    {
        public string TestMethod()
        {
            return "Version 2-PROD Version";
        }
    }

    [ComDefaultInterface(typeof(ITestTrade))]
    [ClassInterface(ClassInterfaceType.None)]
    public class TestTrade : ITestTrade
    {
        public string TradeName { get; set; }
        public int QuantityNumber { get; set; }
    }
}

在Excel VBA中:

Dim objTestClass As ComTest.TestClass
Set objTestClass = New ComTest.TestClass
Dim str As String
objTestClass. ---> I GET ITestTrade methods in objTestClass

Dim tTestTrade As ComTest.TestTrade
Set tTestTrade = New ComTest.TestTrade
tTestTrade. -----> I GET ITestClass methods in tTestTrade

但是,如果我删除'ComTest'并只使用类名,这样可以正常工作。即,

Dim objTestClass As TestClass
Set objTestClass = New TestClass
Dim str As String
objTestClass. ---> I GET ITestClass types

Dim tTestTrade As TestTrade
Set tTestTrade = New TestTrade
tTestTrade. -----> I GET ITestTrade

有人可以帮我理解这一点。

2 个答案:

答案 0 :(得分:1)

我没有找到确切原因。但显然我的tlb注册中出现了问题,以及我将类型暴露给COM的方式。如果您遇到类似问题,这可能对某人有所帮助:

我能够通过以下方式阻止它:

  • 具有程序集的程序集guid属性。 (在assemblyinfo.cs中)
  • 特别提到每个类的GUID属性并公开接口。
  • 使用以下方式公开.Net类

    [ComVisible(true)]
    [ComDefaultInterface(typeof(IEvfExternalClient))]
    [ClassInterface(ClassInterfaceType.None)]
    public class EvfExternalClient : IEvfExternalClient
    {
    }
    

答案 1 :(得分:0)

如果您遇到此问题,请务必为上面提到的每个接口和类创建一个唯一的GUID并使用[ComVisible(true)],但请注意除非在不同的情况下使用[ComDefaultInterface(typeof(...))]是不必要的:{ {3}}

以下是正确的语法:

[Guid(...)]
[ComVisible(true)]
public interface ITestClass
{
    [DispId(1)]
    string TestMethod();
}

[Guid(...)]
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
public class TestClass : ITestClass
{
    public string TestMethod()
    {
        return "Version 2-PROD Version";
    }
    public TestClass() : base() { }
}

这可以防止意外行为。您还需要一个无参数的构造函数,您也可以显式继承System.Object Is there any purpose of ComDefaultInterface for a COM Callable Wrapper?

语法改变了一点,因为答案标记正确。