Results 1 to 18 of 18

Thread: [RESOLVED] Exposing an instance property as shared

  1. #1

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Resolved [RESOLVED] Exposing an instance property as shared

    Suppose I have a class of objects called Porky with a property called IsHuge:
    Code:
    Public Class Porky
       Public Property IsHuge As Boolean
    End Class
    Now I want to make a special kind of Porky -- let's call it UberPorky -- for which I want to change ALL instances to either IsHuge or not IsHuge. What I'd like to do is this:
    Code:
    Public Class UberPorky
    Inherits Porky
       Public Overrides Shared Property IsHuge As Boolean
           Get
               Return MyBase.IsHuge
           End Get
           Set(value As Boolean)
               MyBase.IsHuge = Value
           End Set
       End Property
    End Class
    The trouble is, I can't do that. I'm not allowed to reference MyBase or Me in a Shared property. So can anyone advise me on the right way to do it?

    BB

  2. #2
    PowerPoster motil's Avatar
    Join Date
    Apr 2009
    Location
    Tel Aviv, Israel
    Posts
    2,143

    Re: Exposing an instance property as shared

    the base property IsHuge is not declared as shared, if you want to that property to effect all instances declare it as shared
    * Rate It If you Like it

    __________________________________________________________________________________________

    "Programming is like sex: one mistake and you’re providing support for a lifetime."

    Get last SQL insert ID

  3. #3
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Exposing an instance property as shared

    Dont make it Shared then - if you want a property to always return one specific value then just make it always return that value:

    vb Code:
    1. Public Class UberPorky : Inherits Porky
    2.  
    3.     Public Overloads ReadOnly Property IsHuge As Boolean
    4.         Get
    5.             Return True
    6.         End Get
    7.     End Property
    8.  
    9. End Class
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  4. #4

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Exposing an instance property as shared

    Quote Originally Posted by motil View Post
    the base property IsHuge is not declared as shared, if you want to that property to effect all instances declare it as shared
    Thanks Motil. I don't want all Porkys to be the same, only all UberPorkys. So I can't make the base class IsHuge property Shared.

    Quote Originally Posted by chris128
    Dont make it Shared then - if you want a property to always return one specific value then just make it always return that value:

    Code:
          Public Class UberPorky : Inherits Porky
              Public Overloads ReadOnly Property IsHuge As Boolean
                  Get
                      Return True
                  End Get
              End Property
          End Class
    Hmm. Looks like the opposite of Motil. But main thing I want is to be able to Set IsHuge to True or False for all UberPorkys, leaving ordinary Porkys unchanged. The Get isn't so important.

    Any further ideas?

    tia, BB

  5. #5
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Exposing an instance property as shared

    I think you're going to need to explain yourself a little better, because this isn't making much sense.

    Making your property Shared does not mean that it will take on the same value for every instance of UberPorky. Infact, the property isn't even accessible via any instance of UberPorky, precisely because it is Shared. You can only use it as
    Code:
    UberPorky.IsHuge = True
    and not
    Code:
    Dim u As New UberPorky()
    u.IsHuge = True ' doesnt work!

    After reading your first post, my thought was simply to use a (Shared!) private backing field for the propery:
    vb.net Code:
    1. Public Class UberPorky
    2.     Inherits Porky
    3.  
    4.     Private Shared _IsHuge As Boolean
    5.     Public Shared Shadows Property IsHuge As Boolean
    6.         Get
    7.             Return _IsHuge
    8.         End Get
    9.         Set(ByVal value As Boolean)
    10.             _IsHuge = value
    11.         End Set
    12.     End Property
    13.  
    14. End Class
    But judging from your last post, that is not what you want either. You are talking about 'all UberPorkys', which I interpret as 'all instances of UberPorky'. But you cannot get/set this property for an instance of UberPorky, because it is shared.

    If you do want to set the property for all instances of UberPorky, you'd need to keep a list of them and loop through it, setting them all.

  6. #6
    PowerPoster motil's Avatar
    Join Date
    Apr 2009
    Location
    Tel Aviv, Israel
    Posts
    2,143

    Re: Exposing an instance property as shared

    Quote Originally Posted by NickThissen View Post
    Making your property Shared does not mean that it will take on the same value for every instance of UberPorky
    as far as i know making a property / field as shared will cause all instances of the object to share the same value, I'm still learning this subject so please fix me if i'm wrong.
    Last edited by motil; May 24th, 2010 at 09:53 AM.
    * Rate It If you Like it

    __________________________________________________________________________________________

    "Programming is like sex: one mistake and you’re providing support for a lifetime."

    Get last SQL insert ID

  7. #7
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Exposing an instance property as shared

    That makes no sense because a shared property does not exist for instances of your class. There is only one value.

    Suppose 'IsHuge' is a shared property, then according to you, this code:
    Code:
    Dim a As New UberPorky()
    Dim b As New UberPorky()
    
    a.IsHuge = True
    b.IsHuge = False
    would result in a.IsHuge being False, because the value is shared between instances?

    Well no, because that code doesn't even work. You can't access "IsHuge" on an instance of UberPorky, because it's shared. What you can do is this
    Code:
    Dim a As New UberPorky()
    Dim b As New UberPorky()
    
    UberPorky.IsHuge = True
    UberPorky.IsHuge = False
    And now (note I'm not even using instances a and b) I hope everyone can agree that UberPorky.IsHuge will be False. There is only one value, you are not changing a value for every instance.

  8. #8
    PowerPoster motil's Avatar
    Join Date
    Apr 2009
    Location
    Tel Aviv, Israel
    Posts
    2,143

    Re: Exposing an instance property as shared

    i know that you can not call static member / method from an object instance you can call it only from a class level and that's exactly what i'm saying, memory for static member allocated only once (well you can reset it every time a new instance is created with static / shared constructor)

    EDIT: you can reset its value if you won't put it inside a static constructor, otherwise it's data will be reset each time you'll create new instance.
    Last edited by motil; May 24th, 2010 at 09:53 AM.
    * Rate It If you Like it

    __________________________________________________________________________________________

    "Programming is like sex: one mistake and you’re providing support for a lifetime."

    Get last SQL insert ID

  9. #9
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Exposing an instance property as shared

    Ok, it turns out I wasn't completely right, because you can access the shared properties on an instance (though you will get a warning). But my point remains the same: you aren't accessing any property of the instance, you are using the class (shared) property, and there's only one of them.

    Boops boops: is my last suggestion in post 5 what you are looking for?

  10. #10

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Exposing an instance property as shared

    @Nick. I suspect keeping a List of the instances is the only way. I'll move to a real example, although I think it's been useful to start with an abstraction.

    I've created a class which inherits TabPage called DBTabPage.
    Code:
    Public Class DBTabPage
       Inherits TabPage
       Public Sub New
           Me.DoubleBuffered = True
       End Sub
    End Class
    I would like to be able to switch double buffering on or off for all the DBTabPages by clicking a button. The button sub should ideally do this:
    Code:
    DBTabPage.DoubleBuffered = Not DBTabPage.DoubleBuffered
    But I can't find a way to expose a Shared version of DBTabPage's inherited DoubleBuffered property. Have I missed something obvious? Or would it be a transgression of some OOP principle?

    BB

  11. #11
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Exposing an instance property as shared

    Whether it's possible or not using your current idea, I don't really know. It is a very strange way to accomplish something very simple... I'm assuming these DBTabPages are shown in a TabControl? Why not inherit the TabControl too, and add a DoubleBuffered property to that:
    Code:
    Private _DoubleBuffered As Boolean
    Public Property DoubleBuffered() As Boolean
       Get
          Return _DoubleBuffered
       End Get
       Set(ByVal value As Boolean)
          For Each tab In Me.TabPages.Cast(Of DBTabPage)  'LINQ.. use normal loop if you cant use LINQ
             tab.DoubleBuffered = value
          Next
          _DoubleBuffered = value
       End Set
    End Property

  12. #12

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Exposing an instance property as shared

    The list method is certainly possible. I prefer to give the class itself a Shared list of instances. This helps because I am moving everything to a UserControl instead of a tab page. But this is how it looked:
    Code:
    Public Class DBTabPage
       Inherits TabPage
      
       Public Shared Pages As New List(Of DBTabPage)
    
       Public Overrides Property DoubleBuffered As Boolean
           Get
               Return MyBase.DoubleBuffered
           End Get
           Set (value As Boolean)
               MyBase.DoubleBuffered = value
           End Set
        End Property
    
       Public Sub New
           Pages.Add(Me)
           Me.DoubleBuffered = True
       End Sub
      
     'and Pages.Remove(Me) in Dispose.
    
    End Class
    The DoubleBuffered property has to be overriden to change it from Protected to Public, but it works: you can loop through DBTabPage.Pages to set all instances of DBTabPage to DoubleBuffered=False/True. It's not drastically complicated, but to make the property Shared would have been a nice simplification. I wonder why it's apparently prohibited?

    BB

  13. #13
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Exposing an instance property as shared

    Quote Originally Posted by boops boops View Post
    I'll move to a real example, although I think it's been useful to start with an abstraction.
    awww you mean Porky and UberPorky were not real examples?
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  14. #14
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: Exposing an instance property as shared

    I, too, am disappointed that Porky and UberPorky are contrived examples. I was going to ask for an explanation for the project, cause it sounded like a hoot.

    How about putting a shared member on the derived class, which is exposed via a property. Then, overload the base class property, and in the get or set, set the instance property to the value of the shared property. As long as the only access to the overloaded instance is via the property (as it should be), then any attempt to read or write to the property will cause it to take on the shared value. Unfortunately, for the specific property that you are talking about, this may not be adequate.
    My usual boring signature: Nothing

  15. #15

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Exposing an instance property as shared

    My apologies, Chris and Shaggy. The legal department warned me about letting any more slip until they sorted out the licensing. But we just succeeded in taking over our Columbian competitor ¿Porqué?. Redmond has a patent pending on the upside-down question mark, so I still have to be a bit cautious, but a pre-concept relaunch is in order.

    Shaggy, was this the kind of thing you had in mind?
    Code:
    Public Class Porky
        Protected Property IsHuge() As Boolean
            Get
            End Get
            Set(ByVal value As Boolean)
            End Set
        End Property
    End Class
    
    Public Class UberPorky
        Inherits Porky
        Private Shared _IsHuge As Boolean
        Public Overloads Shared Property IsHuge() As Boolean
            Get
                Return _IsHuge
            End Get
            Set(ByVal value As Boolean)
                _IsHuge = value
                MyBase.IsHuge = value
            End Set
        End Property
    End Class
    
    Public Class ConsumerClass
        Public Sub PokeFat()
            UberPorky.IsHuge = True
        End Sub
    End Class
    I regret that I always get one or the other error. If UberPorky.IsHuge is Shared as above, I am not allowed to address MyBase. If I omit Shared, the ConsumerClass complains that I can only address IsHuge through an instance. Can we get any further from here?

    BB

  16. #16
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: Exposing an instance property as shared

    I still can't understand why you want to do it like this... If you want to set the Text property of all Buttons in a list, you loop through the list and set them individually. If you want to set the Width property of all TextBoxes in a list, you loop through the list and set them individually. If you want to set the DoubleBuffered property of all DBTabPages in a list, you loop through the list and set them individually...! Why not? Why does it have to be different in this case?

    The DoubleBuffered property is an instance member, there's no getting around that. So, you cannot set it using a shared member, unless that shared member has access to a list of all instances and can loop through the list, setting each property individually (where did I hear that before? ).

  17. #17
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,109

    Re: Exposing an instance property as shared

    That wasn't quite where I was going. I was suggesting that the overload of IsHuge be left unshared in a fashion something like this:
    Code:
    Private Shared _AlternateHuge As Boolean
        
    Public Overloads Property IsHuge() As Boolean
            Get
                MyBase.IsHuge = _AlternateHuge
                Return _AlternateHuge
            End Get
            Set(ByVal value As Boolean)
                _AlternateHuge = value
                MyBase.IsHuge = value
            End Set
        End Property
    By doing this (doing it correctly, anyways, as I left off the class name when accessing _AlternateHuge, for no good reason, and this foolish explanation took longer than just fixing it), anybody accessing any instance of the derived class property will see the value of the shared member, while the instance member will be set to the value of the shared member when the property is accessed for either reading or writing. As long as the value is of little significance, this would work seamlessly as far as outside observers are concerned.

    Unfortunately, as I noted earlier, the actual property you are dealing with is not some insignificant state variable for the class. The drawback of the design is that any instance that accesses the member directly before the property has been accessed, will not see the shared value. For a class that was entirely built by you, that could be managed for by either always going through the property, or by setting the property to the shared value in any method that accessed the member. A hokey solution, to be sure, but consistent with the intent of the class that the external observer would see it acting as expected, regardless of the grime beneath the hood.

    Since the property you are dealing with is not just an insignificant state variable, the delay between setting the shared member and accessing the property for any instance (at which time the instance property would be set from the shared member), is probably unacceptable.

    Thus I agree with Nick. Just do it in a loop.
    My usual boring signature: Nothing

  18. #18

    Thread Starter
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,201

    Re: Exposing an instance property as shared

    I want to be able to order my UberPorkies to Jump or not, or be _IsHuge or not, without having to go through a list and address them one by one. For example, I want to be able to command:
    Code:
    UberPorky.AllAreHuge = Not UberPorky.AllAreHuge
    Besides, I don't want to expose the list; there are spies everywhere. No matter, I can make the list Private and let them sort it out for themselves:
    vb.net Code:
    1. Private Shared _UberPorkies As New List(Of UberPorky)
    2. Public Shared Property AreAllHuge() As Boolean
    3.     Get
    4.         For Each u As UberPorky In _UberPorkies
    5.             If u.IsHuge = False Then Return False
    6.         Next
    7.         Return True
    8.     End Get
    9.     Set(ByVal value As Boolean)
    10.         For Each u As UberPorky In _UberPorkies
    11.             u.IsHuge = value
    12.         Next
    13.     End Set
    14. End Property
    In this example Get returns False if only one UberPorky is deviant, but it could obviously be modified to return True for at least one UberPorky.IsHuge, >50% etc. Since IsHuge is Protected in the base class, I still need to Shadow it:
    vb.net Code:
    1. Public Shadows Property IsHuge() As Boolean
    2.         Get
    3.             Return MyBase.IsHuge
    4.         End Get
    5.         Set(ByVal value As Boolean)
    6.             MyBase.IsHuge = value
    7.         End Set
    8.     End Property
    The list is updated in Constructors/Destructors. I have checked whether this works for my "real" protected property, Control.DoubleBuffered, and it does. So barring further comments I reckon this is thread is resolved. Thanks Nick and Shaggy (and others) for helping me think this through. Plaudits where possible. BB
    Last edited by boops boops; May 25th, 2010 at 06:34 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width