Core4: Flexibility with implementing properties


[This post is part of a series, “wish-list for future versions of VB“]


IDEA: Flexibility with implementing properties. Allow you to implement a property with more accessors than was specified in the interface your implementing, or the abstract class you’re inheriting from.


SCENARIO: An interface declares a readonly property, but you want to implement it with a private setter:



Interface I


    ReadOnly Property p As Integer


End Interface


 


Class C


    Implements I


    Private _p As Integer


 


    Public Property p As Integer Implements I.p


        Get


            Return _p


        End Get


        Private Set(ByVal value As Integer)


            _p = value


        End Set


    End Property


End Class


SCENARIO: One interface has a readonly property, and another has a writeonly property, and you want to implement them both at the same time.



Interface IProducer(Of Out T)


    ReadOnly Property p() As T


End Interface


 


Interface IConsumer(Of In T)


    WriteOnly Property p() As T


End Interface


 


Class C(Of T)


    Implements IProducer(Of T)


    Implements IConsumer(Of T)


    Private _p As T


 


    Public ReadOnly Property p As T Implements IProducer(Of T).p, IConsumer(Of T).p


        Get


            Return _p


        End Get


        Set(ByVal value As T)


            _p = value


        End Set


    End Property


End Class


 


Bill Sheldon suggested that maybe the “Implements” clause in the first scenario should go on the Getter or Setter that it’s appropriate to.


 


Provisional evaluation from VB team: This is a decent idea, one that we should consider against all the other decent ideas.

Comments (3)

  1. Dzonny says:

    Why limit possibility to add accessors to properties from interfaces and abstract classes?

    What about this?

    Class ReadOnlyCollection

       Public Overridable ReadOnly Property CanAdd() As Boolean

           Get

               Return False

           End Get

       End Property

    End Class

    Class ReadWriteCollection

       Inherits ReadOnlyCollection

       Private _CanAdd As Boolean = True

       Public Overrides Property CanAdd() As Boolean

           Get

               Return _CanAdd

           End Get

           Set

              _CanAdd = value

           End Set

       End Property

    End Class

    Other scenario – what about possibility to widen assessor accessibility:

    Class BaseClasss

       Private _Changed As Boolean

       Public Virtual Property Changed As Boolean

           Get

               Return _Changed

           End Get

           Protected Set

               _Changed = value

           End Set

       End Property

    End Class

    Class DerivedClass

       Inherits BaseClass

       Public Overrides Property Changed() As Boolean

           Get

               Return MyBase.Changed

           End Get

           Shadows Set ‘Public

               MyBase.Changed = value

           End Set

       End Property

    End Class

    Having Implements / Overrides / Shadows on Getter / Setter instead of on property can clarify what we are doing. Especially with Implements I prefer having in on Property. Lets make both possible.

    Following scenario is more joke than serious request, but technically possible, isn’t it?

    Interface IFace(Of T)

       Property Value As T

    End Interface

    Class Face

       Implements IFace(Of Integer)

       Private _Value As Integer

       Public ReadOnly Property Value As Integer

           Get Implements IFace(Of Integer).Value

               Return _Value

           End Get

       End Property

       Private Sub SetValue(value as Integer) Implements IFace(Of Integer).Value.Set

           _Value = value

       End Sub

    End Class

    🙂

  2. Kevin Ryall says:

    It would be useful  to be able to make a property writeable when defined as ReadOnly on the base class / interface. Doing so wouldn’t violate the contract, but would allow more flexibility in class hierarchies.

    I have an interface called IView which is implemented by all my (MVP style) view classes – generally through an abstract base class called ViewBase. The interface has a read-only property called User to get a reference to the user account the view is running under. Normally the user is injected in the constructor and never changed subsequently, so it makes sense to be a read-only property. However, there are some classes – primarily test classes, but also classes related to the security infrastructure – where it is necessary to be set the user after instantiation. For these cases (and other reasons), I have a view derived from IView called ISecurityView – among other things, this adds a method called SetUser to update the view’s user. It would be simpler / more consistent to just make the property writeable as this is effectively what I am doing, but the language inflexibility forces me to use a mutator method instead – and that’s ugly whn combined with a property.

    Having more flexibility around property implementation isn’t a massive issue, but it does would let me get a bit closer to expressing what I actually want instead of working around the language syntax.

  3. Rowland Shaw says:

    This would be extremely useful, and allow parity with C# code.

    In my opinion, an Interface should define the *minimum* accessibility for a member, and an implementation should be allowed to exceed that implementation if it desires (for example, an interface could define it as ReadOnly, but an implementer may want to make it read/write so that they can use the default Xmlserializers)

    See also my post at:

    http://stackoverflow.com/questions/2362381/protected-set-in-vb-net-for-a-property-defined-in-an-interface