Wrapper classes

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Dave Moran

    #1

    Wrapper classes

    This may be a trivial question, but it's stumping me.

    Public Class A

    End Class

    Public Class B
    Inherits A

    Public Sub New B(ByRef a as A)
    'I want this class to reference 'a' and not copy it.
    End Sub
    End Class

    The idea is that you provide an instance of the base class 'A' and wrap
    class 'B' around the same instance to provide extra functionality. I want to
    specialise class 'A' into class 'B'. How do I do this?

    Dave
  • tomb

    #2
    Re: Wrapper classes

    Dave Moran wrote:
    [color=blue]
    >This may be a trivial question, but it's stumping me.
    >
    >Public Class A
    >
    >End Class
    >
    >Public Class B
    > Inherits A
    >
    > Public Sub New B(ByRef a as A)
    > 'I want this class to reference 'a' and not copy it.
    > End Sub
    >End Class
    >
    >The idea is that you provide an instance of the base class 'A' and wrap
    >class 'B' around the same instance to provide extra functionality. I want to
    >specialise class 'A' into class 'B'. How do I do this?
    >
    >Dave
    >
    >[/color]
    If you only want a reference to A, then don't inherit A, just dim a
    variable of type A, and assign it equal to a.

    Comment

    • Jay B. Harlow [MVP - Outlook]

      #3
      Re: Wrapper classes

      Dave,
      ByRef & ByVal are how parameters are passed.

      Class & Structure are how variables are stored.


      Remember Class is a reference type, which means a variable of a Class type
      holds a reference to the actual object. The object itself is on the heap.

      Where as Structure & Enum are value types, which means a variable of a
      Structure or Enum type holds the actual value. This variable could be
      either on the stack in the case of parameters & local variables or on the
      head in the case of member fields.

      When you pass something ByRef you are passing a reference to the passed
      variable. Whereas if you pass something ByVal you are passing a copy of the
      passed variable.

      Which means if you pass a variable of a Class type ByRef, you are passing a
      reference to a reference to an object. Where as if you pass variable of a
      Class type ByVal you are passing a copy of the reference to an object.

      You should "only" use ByRef when you want the called routine to be able to
      modify the passed variable itself. For example you want to return multiple
      values from a routine.

      That being said, you simply pass a class ByVal when you want to copy the
      reference to the object on the heap.

      For example, you would do something like:

      Public Class A

      Public Overridable Sub Something()

      End Sub

      End Class

      Public Class B
      Inherits A

      Private ReadOnly m_wrapped As A

      Public Sub New(ByVal a As A)
      m_wrapped = a
      End Sub

      Public Overrides Sub Something()
      m_wrapped.Somet hing()
      End Sub

      End Class

      Here is a more involved example:

      ---x--- cut here ---x--- begin TraceStream.vb ---x---
      Option Strict On
      Option Explicit On

      Imports System.IO

      Public Class TraceStream
      Inherits Stream

      Private ReadOnly m_stream As Stream

      Public Sub New(ByVal stream As Stream)
      If stream Is Nothing Then Throw New ArgumentNullExc eption("stream" )
      m_stream = stream
      End Sub

      Private Sub WriteTrace(ByVa l format As String, ByVal ParamArray args()
      As Object)
      Dim message As String = String.Format(f ormat, args)
      Trace.WriteLine (message, "TraceStrea m")
      End Sub

      Public Overrides ReadOnly Property CanRead() As Boolean
      Get
      Return m_stream.CanRea d
      End Get
      End Property

      Public Overrides ReadOnly Property CanSeek() As Boolean
      Get
      Return m_stream.CanSee k
      End Get
      End Property

      Public Overrides ReadOnly Property CanWrite() As Boolean
      Get
      Return m_stream.CanWri te
      End Get
      End Property

      Public Overrides ReadOnly Property Length() As Long
      Get
      Return m_stream.Length
      End Get
      End Property

      Public Overrides Property Position() As Long
      Get
      Return m_stream.Positi on
      End Get
      Set(ByVal value As Long)
      WriteTrace("Pos ition={0}", value)
      m_stream.Positi on = value
      End Set
      End Property

      Public Overrides Sub Flush()
      WriteTrace("Flu sh")
      m_stream.Flush( )
      End Sub

      Public Overrides Function Read(ByVal buffer() As Byte, ByVal offset As
      Integer, ByVal count As Integer) As Integer
      WriteTrace("Rea d(buffer={0}, offset={1}, count={2})", buffer,
      offset, count)
      Return m_stream.Read(b uffer, offset, count)
      End Function

      Public Overrides Function Seek(ByVal offset As Long, ByVal origin As
      System.IO.SeekO rigin) As Long
      WriteTrace("See k(offset={0}, origin={1})", offset, origin)
      Return m_stream.Seek(o ffset, origin)
      End Function

      Public Overrides Sub SetLength(ByVal value As Long)
      WriteTrace("Set Length(value={0 })", value)
      m_stream.SetLen gth(value)
      End Sub

      Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As
      Integer, ByVal count As Integer)
      WriteTrace("Wri te(buffer={0}, offset={1}, count={2})", buffer,
      offset, count)
      m_stream.Write( buffer, offset, count)
      End Sub

      Public Overrides Sub WriteByte(ByVal value As Byte)
      WriteTrace("Wri teByte(value={0 })", value)
      m_stream.WriteB yte(value)
      End Sub

      End Class
      ---x--- cut here ---x--- end TraceStream.vb ---x---



      --
      Hope this helps
      Jay B. Harlow [MVP - Outlook]
      ..NET Application Architect, Enthusiast, & Evangelist
      T.S. Bradley - http://www.tsbradley.net


      "Dave Moran" <dmoran@nospam. nospam> wrote in message
      news:3843E52B-EA7C-450E-97FC-25E8752220E5@mi crosoft.com...
      | This may be a trivial question, but it's stumping me.
      |
      | Public Class A
      |
      | End Class
      |
      | Public Class B
      | Inherits A
      |
      | Public Sub New B(ByRef a as A)
      | 'I want this class to reference 'a' and not copy it.
      | End Sub
      | End Class
      |
      | The idea is that you provide an instance of the base class 'A' and wrap
      | class 'B' around the same instance to provide extra functionality. I want
      to
      | specialise class 'A' into class 'B'. How do I do this?
      |
      | Dave


      Comment

      • Dave Moran

        #4
        Re: Wrapper classes

        Hi Jay

        Thanks very much for the detailed response. I've been on vacation and so
        haven't been able to reply.

        Your explanation makes sense to me, with one small exception. Why do I still
        need to inherit from class A? Is this so class B appears to be derived from
        class A?

        If I wanted to add more specialization using class C, derived from class B,
        is my example below correct? How do I handle creating an instance of class C
        from an instance of class A? Should I cast it?

        Thanks

        Dave



        Public Class A

        Public Overridable Sub Something()

        End Sub

        End Class

        Public Class B
        Inherits A

        Private ReadOnly m_wrappedA As A

        Public Sub New(ByVal a As A)
        m_wrappedA = a
        End Sub

        Public Overrides Sub Something()
        m_wrappedA.Some thing()
        End Sub

        End Class

        Public Class C
        Inherits B

        Private ReadOnly m_wrappedB As B

        Public Sub New(ByVal a As A)
        m_wrappedB = a 'What do I do here?
        End Sub

        Public Sub New(ByVal b As B)
        m_wrappedB = b
        End Sub

        Public Overrides Sub Something()
        m_wrappedB.Some thing()
        End Sub

        End Class

        Comment

        • Walter Wang [MSFT]

          #5
          Re: Wrapper classes

          Hi Dave,

          When B inherits from A, B is-a A. When B wraps A, B has-a A.

          Actually your question is all about the classic Decorator design pattern.
          You can find more info here:

          #Decorator Design Pattern in C# and VB.NET
          DLearn how to use the C# Decorator design pattern to add new functionality to existing objects without modifying their classes, with quick and easy examples. 100% Source code.


          #.NET Matters: Stream Decorator
          http://msdn.microsoft.com/msdnmag/is...09/NETMatters/

          Hope this helps. If anything is unclear, please feel free to post here.

          Regards,
          Walter Wang
          Microsoft Online Community Support

          =============== =============== =============== =====
          When responding to posts, please "Reply to Group" via your newsreader so
          that others may learn and benefit from your issue.
          =============== =============== =============== =====

          This posting is provided "AS IS" with no warranties, and confers no rights.

          Comment

          • Jay B. Harlow [MVP - Outlook]

            #6
            Re: Wrapper classes

            Dave,
            You don't per se:

            However its what you are apparently asking for.

            <quote>
            The idea is that you provide an instance of the base class 'A' and wrap
            class 'B' around the same instance to provide extra functionality. I want to
            specialise class 'A' into class 'B'. How do I do this?
            </quote>

            "base class A" implies inheritance. "specialize class A" implies
            inheritance. Now it may just be a case of nomenclature...


            As Walter states, you use inheritance when you want B *is a* A. You use
            wrapping (delegation) when B *has a* A.

            You use both as I showed (and you are seemingly asking) when B is both *is
            a* and *has a*, commonly a decorator. For example the TraceStream I showed
            is a stream as it can be used any place a stream is used, plus it has a
            stream as it operates on a second stream (the actual stream)...
            BufferedStream does something similar.

            Using both is an advanced topic.

            --
            Hope this helps
            Jay B. Harlow [MVP - Outlook]
            ..NET Application Architect, Enthusiast, & Evangelist
            T.S. Bradley - http://www.tsbradley.net


            "Dave Moran" <dmoran@nospam. nospam> wrote in message
            news:D8BBD789-854E-4876-AD66-B9C7F3A9E473@mi crosoft.com...
            | Hi Jay
            |
            | Thanks very much for the detailed response. I've been on vacation and so
            | haven't been able to reply.
            |
            | Your explanation makes sense to me, with one small exception. Why do I
            still
            | need to inherit from class A? Is this so class B appears to be derived
            from
            | class A?
            |
            | If I wanted to add more specialization using class C, derived from class
            B,
            | is my example below correct? How do I handle creating an instance of class
            C
            | from an instance of class A? Should I cast it?
            |
            | Thanks
            |
            | Dave
            |
            |
            |
            | Public Class A
            |
            | Public Overridable Sub Something()
            |
            | End Sub
            |
            | End Class
            |
            | Public Class B
            | Inherits A
            |
            | Private ReadOnly m_wrappedA As A
            |
            | Public Sub New(ByVal a As A)
            | m_wrappedA = a
            | End Sub
            |
            | Public Overrides Sub Something()
            | m_wrappedA.Some thing()
            | End Sub
            |
            | End Class
            |
            | Public Class C
            | Inherits B
            |
            | Private ReadOnly m_wrappedB As B
            |
            | Public Sub New(ByVal a As A)
            | m_wrappedB = a 'What do I do here?
            | End Sub
            |
            | Public Sub New(ByVal b As B)
            | m_wrappedB = b
            | End Sub
            |
            | Public Overrides Sub Something()
            | m_wrappedB.Some thing()
            | End Sub
            |
            | End Class
            |


            Comment

            Working...