Ошибка несоответствия типа при передаче дочернего типа подпрограмме, принимающей родительский тип VBA

Контекст

У меня есть родительский интерфейс, IParent,

Option Explicit

Public Sub DoParentStuff()
End Sub

дочерний интерфейс, реализующий IParent, IChild,

Option Explicit

Implements IParent

Private Sub IParent_DoParentStuff()
End Sub

Public Sub DoParentStuff()
End Sub

и конкретная реализация IChild, CStandardChild.

Option Explicit

Implements IChild

Private Sub IChild_DoParentStuff()
End Sub

Public Sub DoParentStuff()
  IChild_DoParentStuff
End Sub

Затем я создал модуль, который передает переменную типа IChild подпрограмме с одним параметром типа IParent.

Option Explicit

Private Sub Test(ByRef parent As IParent)
  parent.DoParentStuff
End Sub

Public Sub Main()
  Dim child As IChild
  
  Set child = New CStandardChild
  
  Test child
End Sub

Я могу скомпилировать проект VBA без ошибок. Но когда я запускаю Main, я получаю ошибку времени выполнения

Ошибка выполнения «13»:

Несоответствие типов

Отладчик указывает на код Test child.

Вопрос

Почему во время выполнения я получаю ошибку несоответствия типов? Как я могу передать child в Test(), не получая этой ошибки?

Что я пробовал

Я изучал приведение IChild к IParent. Однако я не использую VB.NET, поэтому у меня нет доступа к DirectCast и CType. Говоря это, если я правильно реализовал IParent и IChild, я не думаю, что приведение необходимо.


person Joshua Daly    schedule 12.11.2018    source источник
comment
Я не уверен, что понимаю вопрос. Вы просто ищете способ приведения к IParent в VBA? Просто объявите Dim foo As IParent: Set foo = child   -  person Comintern    schedule 13.11.2018
comment
Привет @Comintern, я пытаюсь передать child в Test(), не получая ошибки Type mismatch. Тем не менее, ваш комментарий может быть способом сделать это, я попробую, спасибо.   -  person Joshua Daly    schedule 13.11.2018


Ответы (1)


Если я правильно понимаю, что вы пытаетесь сделать, похоже, вы пытаетесь расширить IParent с помощью IChild членов. Вы не можете сделать это в VBA — это было бы здорово, но это часть того, что делает .NET более гибкой средой для работы.

Если взять аналогию с С# - это то, что, я думаю, вы пытаетесь сделать (и это незаконно в VBA):

interface IFoo { void DoSomething() }
interface IBar : IFoo { void DoStuff() } // inherits members of IFoo

Если вам нужно, чтобы CStandardChild был доступен через интерфейсы IParent и IChild, вам нужны оба оператора Implements в этом классе:

Option Explicit
Implements IChild
Implements IParent

'implement members of both interfaces...

Затем вы можете передать экземпляр этого класса и «привести» его к любому интерфейсу.

person Mathieu Guindon    schedule 12.11.2018
comment
Спасибо, это здорово знать. - person Joshua Daly; 13.11.2018