Question

So I have a problem in which I have an object that holds other objects that are loosely related to each other. I only want this object to be a sort of repository whereby variables can be read, but not altered if this object is used. This was my starting point (VB.Net):

Public Class CompanyVendorContext
    Private _company As ICompany
    Private _vendor As IVendor

    Public ReadOnly Property Company As ICompany
        Get
            Return Me._company
        End Get
    End Property

    Public ReadOnly Property Vendor As IVendor
        Get
            Return Me._vendor
        End Get
    End Property

    Public Sub New(ByVal objCompany As ICompany, ByVal objVendor As IVendor)
        Me._company = objCompany
        Me._vendor = objVendor
    End Sub
End Class

Now, appropriately, when I try to set the object itself, like so:

Dim context As New CompanyVendorContext(New Company, New Vendor)
context.Company = New Company

It doesn't allow me to do so, which is perfect. However, when I attempt to do this instead:

Dim context As New CompanyVendorContext(New Company, New Vendor)
context.Company.ID = 1

It allows me to do so. Can I set the properties of the Company object as readonly, but only when accessed from this CompanyVendorContext object?

Was it helpful?

Solution

A ReadOnly property only makes that property value read only; it does not affect the behavior of the object that property references. If you need to make a truly read-only instance you'll have to make ICompany immutable, like this:

Public Interface ICompany
    ReadOnly Property Id() As Integer
    ...
End Interface

Of course, some care needs to be taken here as well. If Company (the class which implements ICompany) is mutable, there's nothing stoping a user from doing this:

CType(context.Company,Company).ID = 1

OTHER TIPS

you need to set the ID property to readonly also.

Assuming you don't want to make the property's set accessor private or protected, there's no easy way of doing this without changing the Company class itself to make all of it's properties readonly (and on and on down the line). If the design doesn't allow you to change it, you could write some sort of adapter, proxy or other related design pattern that wraps the objects for each property and doesn't allow for the setting of those properties.

Use an interface when you need to use a readonly like this.

Public Interface ICompanyVendorContext
    ReadOnly Property Company As ICompany
    ReadOnly Property Vendor As IVendor
End Interface

Public Class CompanyVendorContext Implements ICompanyVendorContext

    Private m_Company As ICompany
    Private m_Vendor As IVendor

    Public Property Company As ICompany
        Get
            Return m_AppFolder
        End Get
        Set
            m_AppFolder = Value
        End Set
    End Property

    Public Property Vendor As IVendor
        Get
            Return m_Vendor
        End Get
        Set
            m_Vendor = Value
        End Set
    End Property

    private readonly Property ReadonlyCompany As ICompany implements ICompanyVendorContext.Company
        Get
            Return m_Company
        End Get
    End Property

    private readonly Property ReadonlyVendor As IVendor implements ICompanyVendorContext.Vendor
        Get
            Return m_Vendor
        End Get
    End Property

End Class
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top