2017-01-04 5 views
3

У меня есть ситуация, когда VB.Net COM Class не выполняет функции наследования, доступные для родительского класса при обращении к интерфейсу через VBA.Наследование класса VB.Net Com Class

I.e. У меня есть COM-класс VB.Net (myParent) и подкласс VB.net COM (myChild).

Я искал и нашел что-то похожее здесь: Exposing inherited members of a COM vb.net class, но решение «попробуй это», похоже, не существует?

<ComClass(MyParent.ClassId, MyParent.InterfaceId, MyParent.EventsId)> 
Public Class MyParent 

#Region "COM GUIDs" 
    Public Const ClassId As String = "386e628c-872b-41ee-abb2-d2a5dfb4e51e" 
    Public Const InterfaceId As String = "f4b194f1-9dc9-4f37-93d8-57cb97e05593" 
    Public Const EventsId As String = "4320826d-a02c-4360-b8b5-4c98569c2b2e" 
#End Region 

    Public Sub New() 
     MyBase.New() 
    End Sub 


    Public Function parent_hello_world() As Boolean 
     MsgBox("Hello from Parent") 
     Return True 
    End Function 

End Class 

<ComClass(MyChild.ClassId, MyChild.InterfaceId, MyChild.EventsId)> 
Public Class MyChild 
    Inherits MyParent 

#Region "COM GUIDs" 
    Public Const ClassId As String = "65674d29-7bb7-447e-8282-47b9873cec4a" 
    Public Const InterfaceId As String = "cbcdfb17-c8b9-42e2-bed7-b516b9df6111" 
    Public Const EventsId As String = "22a8959c-7594-4584-b53d-a087246be623" 
#End Region 

    Public Sub New() 
     MyBase.New() 
    End Sub 


    Public Function child_hello_world() As Boolean 
     MsgBox("Hello from Child") 
     Return True 
    End Function 

End Class 

И ниже код (при выполнении из VBA) не:

Sub test_me() 
    Dim tip As New TestInheritance.MyParent 
    Dim tic As New TestInheritance.MyChild 
    tip.parent_hello_world() 'this works - directly from parent 

    tic.child_hello_world() 'this works - child function 
    tic.parent_hello_world() 'throws an error - not accessible? 

End Sub 

Есть ли решение для этого, помимо необходимости переопределить интерфейсы в дочернем классе?

Большое спасибо.

+1

Определите интерфейсы для обоих классов, а дочерний интерфейс реализует базовый интерфейс. Комбакторы COM - это почти всегда только коллекции реализаций интерфейса - создавайте их явно, а не полагайтесь на компилятор, чтобы сделать это за вас. – Comintern

ответ

2

COM использует сверхчистую интерфейсную парадигму под капотом. Вы делаете битву с тем, как она отображается на языках VB.NET и VBA. Наследование реализации является проблемой на стороне VB.NET, компилятор переписывает ваш класс для реализации двух интерфейсов. Интерфейс по умолчанию отображает членов класса, второй интерфейс не по умолчанию отображает унаследованные элементы.

Это проблема на стороне VBA, главным образом потому, что она не имеет прямой поддержки интерфейсов вообще. Вы можете использовать интерфейс по умолчанию напрямую, для получения ссылки на другой интерфейс требуется использовать ключевое слово Set. Как это:

Dim child As New TestInheritance.MyChild 
child.child_hello_world 
Dim parent As TestInheritance.MyParent 
Set parent = child 
parent.parent_hello_world 

Это прекрасно работает, но, конечно, не большая причина быть в восторге от этого. Самая большая проблема заключается в том, что это код, который является полностью неоткрытым. Причина, по которой вы задавали этот вопрос, ничего в диалоговом окне автозаполнения в текстовом редакторе VBA не говорит о том, что это может сработать. Вам нужно написать руководство, чтобы сообщить об этом своему программисту. И если клиент-программист предпочитает позднюю привязку, то он полностью застрял.

Одна вещи, которую вы могли бы рассмотреть, чтобы помочь ему получить это право подвергать базовый класс непосредственно через свойство, о кратчайшем коде вы когда-нибудь написать:

Public ReadOnly Property Parent As MyParent 
    Get 
     Return Me 
    End Get 
End Property 

Сейчас это очень обнаруживаемое в VBA и у вас не возникнет проблем с получением:

Dim child As New TestInheritance.MyChild 
child.child_hello_world 
child.parent.parent_hello_world 
Смежные вопросы