Cascading generic interfaces

爱⌒轻易说出口 提交于 2019-12-24 04:40:25

问题


I am building my own framework to wrap the interfaces exposed via Microsoft.Office.Interop.

I wrap Office-wide functionalities into a first set of interfaces, which are then inherited by a second set of functionalities, which are application-dependent.

Here is a simplified version:

Region "Office Wrappers"

    Interface IApplication(Of T As IFile(Of IVariable))    
        Property Files As IList(Of T)    
    End Interface

    Interface IFile(Of T As IVariable)    
        Property Variables As IList(Of T)    
    End Interface

    Interface IVariable    
    End Interface    

#End Region    

#Region "Word Wrappers"

    Interface IWordApp 'ERROR BC32044
        Inherits IApplication(Of IWordDocument(Of IVariable, IWordParagraph))    
    End Interface

    Interface IWordDocument(Of TVar As IVariable, TPara As IWordParagraph)
        Inherits IFile(Of TVar)    
        Property Paragraphs As TPara    
    End Interface

    Interface IWordVariable
        Inherits IVariable    
    End Interface

    Interface IWordParagraph    
    End Interface

#End Region

The above sample returns an error (see 'ERROR BC32044 comment in the sample):

Type argument 'IWordDocument(Of IWordVariable, IWordParagraph)' does not inherit from or implement the constraint type 'IFile(Of IVariable)'.

In order to fix this, I need to replace IWordVariable by IVariable in two instances:

Interface IWordApp
    Inherits IApplication(Of IWordDocument(Of IVariable, IWordParagraph)) '<- Replacement 1 of 2 here
End Interface

Interface IWordDocument(Of TVar As IVariable, TPara As IWordParagraph) '<- Replacement 2 of 2 here
    Inherits IFile(Of TVar)
    Property Paragraphs As TPara
End Interface

Since IWordVariable inherits from IVariable, I though AnyGeneric(Of T as IVariable) should accept AnyGeneric(Of IWordVariable).

Why does the original code not compile, and how can I fix this?


Additional information & question

I use generics first because each application (Word, Excel, etc) relies on a set of base interfaces (as explained above), but also because I then "extend" each wrapper to expose some custom functionalities. For example:

Interface IExtendedWordDocument
    Inherits IWordDocument(Of IWordVariable, IExtendedWordParagraph)
End Interface

Interface IExtendedWordParagraph
    Inherits IWordParagraph
    Sub SomeCustomActionHere()
End Interface

Having this system of inheritance allows me to unit test my extended wrappers, whilst I am not too worried about the stability of the Office and Word wrappers, as they basically are a mirror of Microsoft.Office.Interop.

Once developing my models, I was hoping to be able to refer to MyApp As IApplication or As IWordApp, where they would implicitly mean As IApplication(Of IFile(Of IVariable)) or As IWordApp(Of IWordDocument(Of IWordVariable, IWordParagraph)). How could I achieve this?

I did try this:

Interface IApplication
    Inherits IApplication(Of IFile(Of IVariable))
End Interface

Interface IWordApp
    Inherits IWordApp(Of IWordDocument(Of IWordVariable, IWordParagraph))
End Interface

But for casting to work properly (when passing an IWordApp where an IApplication is expected), I need to have IWordApp(Of IWordDocument(Of IWordVariable, IWordParagraph)) to inherit IApplication instead of IApplication(Of IFile(Of IVariable)), which results in Me.Variables to expose IVariable, not IWordVariable.

When in reality the cascade of generics looks more like this: IWordApp(Of IDocument(Of IVariables(Of IVariable)), IDocuments(Of IDocument(Of IVariables(Of IVariable)))), you then understand why I am trying to cut the code required within the models.

来源:https://stackoverflow.com/questions/58202355/cascading-generic-interfaces

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!