Home > Back-end >  From A Method With In The Class Return An Instance Of The Class As An Interface Type That The Class
From A Method With In The Class Return An Instance Of The Class As An Interface Type That The Class

Time:07-27

what I'm trying to archive with the code below is to have the GetInstance generic function take in an interface type that SystemVars implements (say IAuthentication) then create an instance of SystemVars and return it as interface type T.

The problem I an having is that no matter what casting method I try I can't find a way to return the new instance of SystemVars as T. The line in the GetInstance method Return <CastingFunction>(New SystemVars,T) always fails to compile with the error message saying Value of type SystemVars cannot be converted to 'T'.

How do I return the instance of the class as the interface type that was passed into T?

Imports System.Drawing

Public Class SystemVars
    Implements IAuthentication,
               IAuthorization,
               IApplicationStarting

    Private Sub New()
    End Sub


    Public Shared Function GetInstance(Of T)() As T
        Return DirectCast(New SystemVars, T)
    End Function


    Public ReadOnly Property Username As String _
        Implements IAuthentication.Username,
                   IAuthorization.Username
        Get
            Return _userName
        End Get
    End Property


    Public ReadOnly Property Rolls As List(Of String) _
        Implements IAuthorization.Rolls
        Get
            Return _rolls
        End Get
    End Property


    Public ReadOnly Property InstallationId As Guid _
        Implements IAuthentication.InstallationId,
                   IApplicationStarting.InstallationId
        Get
            Return _installationId
        End Get
    End Property


    Public ReadOnly Property MainWindowStartUpPlacement As Rectangle _
        Implements IApplicationStarting.MainWindowStartUpPlacement
        Get
            Return _mainWindowStartUpPlacement
        End Get
    End Property

    '........

    Private Shared _userName As String
    Private Shared _rolls As List(Of String)
    Private Shared _installationId As Guid
    Private Shared _mainWindowStartUpPlacement As Rectangle
End Class

CodePudding user response:

You can make an otherwise illegal cast work by passing through Object.

Public Shared Function GetInstance(Of T)() As T
    Return DirectCast(CObj(New SystemVars), T)
End Function

You will get a runtime error if the cast isn't possible; as noted in the comments, this strategy is chucking type safety out the window and basically telling the compiler, "Don't bother me, I know what I'm doing." The runtime will throw an InvalidCastException on failure if you don't test and throw yourself. You can test using Type.IsAssignableFrom if you want to create a more developer-friendly error message; there isn't much context available in the debugger at the point of failure, though it may be pretty obvious if you look up the call stack.

For just three interfaces, it might be better to do three separate specific functions rather than a generic version, especially considering that the functions are necessarily Shared (and thus can't themselves be part of an interface).

  • Related