Типы .NET, неправильно представленные в VBA - PullRequest
1 голос
/ 12 декабря 2011

Я пытаюсь понять это странное поведение в VBA. У меня есть два .NET класса, которые наследуют интерфейсы и открыты для COM. Я регистрируюсь для взаимодействия COM и в VBA я сталкиваюсь с этим странным поведением, когда объекты показывают типы из неправильного интерфейса. Хорошо объяснено в коде, как показано ниже:

C # Класс:

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 ]

1 голос
/ 06 марта 2012

Я не нашел точную причину того, почему это произошло. Но, очевидно, что-то пошло не так в моей регистрации в tlb и в том, как я выставлял свои типы на COM. Это может помочь кому-то, если у вас были похожие проблемы:

Я смог остановить это:

  • Наличие атрибута guid для сборки. (в Assemblyinfo.cs)
  • В частности, упоминание атрибута GUID для каждого класса и предоставление интерфейсов.
  • И используя приведенный ниже способ, чтобы выставить .Net классы

    [ComVisible(true)]
    [ComDefaultInterface(typeof(IEvfExternalClient))]
    [ClassInterface(ClassInterfaceType.None)]
    public class EvfExternalClient : IEvfExternalClient
    {
    }
    
0 голосов
/ 17 апреля 2017

Если у вас возникла эта проблема, определенно создайте уникальный GUID для каждого интерфейса и класса, который вы используете, как указано выше, и используйте [ComVisible(true)], но также обратите внимание, что использование [ComDefaultInterface(typeof(...))] не требуется, за исключением других случаев: Есть лиВы хотите использовать ComDefaultInterface для COM Callable Wrapper? .

Ниже приведен правильный синтаксис:

[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 https://msdn.microsoft.com/en-us/library/ms182203.aspx

Синтаксис немного изменился, поскольку ответ помечен как правильный.

...