Home All Groups Group Topic Archive Search About
Author
25 May 2006 3:15 PM
Dave Moran
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

Author
25 May 2006 5:24 PM
tomb
Dave Moran wrote:

Show quoteHide quote
>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

>
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.
Author
25 May 2006 5:46 PM
Jay B. Harlow [MVP - Outlook]
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.Something()
        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 ArgumentNullException("stream")
        m_stream = stream
    End Sub

    Private Sub WriteTrace(ByVal format As String, ByVal ParamArray args()
As Object)
        Dim message As String = String.Format(format, args)
        Trace.WriteLine(message, "TraceStream")
    End Sub

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

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

    Public Overrides ReadOnly Property CanWrite() As Boolean
        Get
            Return m_stream.CanWrite
        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.Position
        End Get
        Set(ByVal value As Long)
            WriteTrace("Position={0}", value)
            m_stream.Position = value
        End Set
    End Property

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

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

    Public Overrides Function Seek(ByVal offset As Long, ByVal origin As
System.IO.SeekOrigin) As Long
        WriteTrace("Seek(offset={0}, origin={1})", offset, origin)
        Return m_stream.Seek(offset, origin)
    End Function

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

    Public Overrides Sub Write(ByVal buffer() As Byte, ByVal offset As
Integer, ByVal count As Integer)
        WriteTrace("Write(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("WriteByte(value={0})", value)
        m_stream.WriteByte(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


Show quoteHide quote
"Dave Moran" <dmoran@nospam.nospam> wrote in message
news:3843E52B-EA7C-450E-97FC-25E8752220E5@microsoft.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
Author
5 Jun 2006 2:57 PM
Dave Moran
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.Something()
        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.Something()
        End Sub

    End Class
Author
7 Jun 2006 6:50 AM
Walter Wang [MSFT]
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
http://www.dofactory.com/Patterns/PatternDecorator.aspx

#.NET Matters: Stream Decorator
http://msdn.microsoft.com/msdnmag/issues/05/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.
Author
7 Jun 2006 11:55 AM
Jay B. Harlow [MVP - Outlook]
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


Show quoteHide quote
"Dave Moran" <dmoran@nospam.nospam> wrote in message
news:D8BBD789-854E-4876-AD66-B9C7F3A9E473@microsoft.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.Something()
|        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.Something()
|        End Sub
|
|    End Class
|