views:

85

answers:

2

Okay this is a bit of a noobish question, but I ran across this today and it somewhat puzzles me WHY it would be this way.

Consider the following structure

    Public Class Employee
    Implements IPerson

    Private _MyManager As Manager
    Public Property MyManager() As Manager Implements IPerson.TheirLeader
     Get
      Return _MyManager
     End Get
     Set(ByVal value As Manager)
      _MyManager = value
     End Set
    End Property

End Class

Public Class Manager
    Implements IPerson, IAuthorityFigure

    Private _MyBoss As Boss
    Public Property MyBoss() As Boss Implements IPerson.TheirLeader
     Get
      Return _MyBoss
     End Get
     Set(ByVal value As Boss)
      _MyBoss = value
     End Set
    End Property

End Class

Public Class Boss
    Implements IPerson, IAuthorityFigure

    'Implementation code here...

End Class

Public Interface IPerson

    Property TheirLeader() As IAuthorityFigure

End Interface

Public Interface IAuthorityFigure
    'Stuff here...
End Interface

Here is my question: I am wanting to have every person implement the IPerson interface, whether they are an employee, boss, or manager. However, they each have an attribute that refers to their leader (employees have a manager, managers have a boss, etc). Each implementation of their leader could be potentially differnt other than they fact that they implement the IAuthorityFigure interface. I am wanting to have the IPerson interface have a property for the IAuthorityFigure, but it throws a compiler error for me when I implement this b/c the IAuthorityFigure is not the same type as Boss or Manager (even though they implement the interface).

So, I am doing something wrong, or is this a limitation of using interfaces versus abstract classes. If this is a limitation, can anyone explain why it is so?

Thanks!

+1  A: 

You're not doing anything wrong. In all currently released versions of Visual Basic (and C#), the implementation of method, property or field of an interface must exactly match the signature on the interface. There is no way to override this.

The best that you can do is to have 2 properties, one which implmeents the interface and another which is used to return the actual implementation.

Private _MyBoss As Boss
Public Property TheirLeader() As IAuthorityFigure Implements IPerson.TheirLeader
    Get
            Return MyBoss
    End Get
    Set(ByVal value As IAuthorityFigure)
            MyBoss = CType(value, IAuthorityFigure)
    End Set
End Property

Public Property MyBoss As Boos
    Get
            Return _MyBoss
    End Get
    Set(ByVal value As Boss)
            _MyBoss = value
    End Set
End Property
JaredPar
Great idea - I did not think of that approach. In my situation would you use that technique (trying to imagine if there would be any ramifications of doing this).
Nathan
@Nathan, yes i would certainly use that technique in your situation. When I'm dealing with a concrete implementation like Employee I know that the "TheirLeader" is a Manager. I don't want to add a lot of redundant casts to my code so I do the dual property.
JaredPar
The interface implementation property (TheirLeader) setter should take an IAuthorityFigure and cast to Boss in that case (this will not compile, since the value parameter is not of the correct type).I personally do not like it too much, because that allows to send in any IAuthorityFigure and will break at runtime if it is not a Boss instanceDepending on the case, maybe TheirLeader should be read-only (whch takes care of that problem). If it is not, there is some risk.
Denis Troller
Great point! Thanks for the heads up there.
Nathan
@Denis, yes good point. I updated the code.
JaredPar
A: 

It would help if you listed the code defining the IPerson interface. However, I would guess that you need to cast the Manager and Boss as IAuthorityFigure instead of their classes.

Eric