简体   繁体   中英

Why can't I recast my concrete type as an interface

I am looking to implement the ability to compare and sort classes in my model. All of the objects in my model will need some common functionality regarding to comparisons so I created an abstract BaseComparer that implements IComparer .

Public MustInherit Class BaseComparer(Of T)
    Implements IComparer(Of T)
End Class

Each class in the model has its own concrete implementation of BaseComparer .

Public Class PersonComparer
    Inherits BaseComparer(Of Person)
End Class

Then I have a ComparerFactory that is responsible for creating and initializing the comparers:

Public Class ComparerFactory
    Public Shared Function GetComparer(ByVal target As Type) As IComparer

        If target Is GetType(Person) Then
            Return New PersonComparer()

        ElseIf target Is GetType(Organization) Then
            Return New OrganizationComparer()

        ElseIf 'etc...
        End If
    End Function
End Class

The problem is that ComparerFactory.GetComparer throws following error . Interestingly enough, the code compiles fine, but it only errors at runtime.

Unable to cast object of type 'PersonComparer' to type 'System.Collections.IComparer'.

PersonComparer inherits from BaseComparer which implements IComparer . What am I missing here? Why can't it be cast? I suspect it has something to do with IComparer(Of T)

Your abstract class implements the generic interface IComparer(Of T) , but not the non-generic interface IComparer . These are actually two different interfaces, which are not related to each other, not even by inheritance.

You can simply have your abstract class implement both interfaces:

Public MustInherit Class BaseComparer(Of T)
    Implements IComparer(Of T), IComparer
End Class

There are two different interfaces:

IComparer (http://msdn.microsoft.com/en-us/library/system.collections.icomparer.aspx)

and

IComparer<T> (http://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx)

The latter generic interface does not inherit from the former.

I would suggest making your BaseComparer directly implement the non-generic IComparer as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM