I have a class inside another class that has public access called SampleRating
.
There is a list of objects of the type of SampleRating
called SampleRatings
.
The data stored in the list items should never be changed after it is initially set, only queried. The list itself should also never be changed.
What is the correct way of making the list and the values therein, have a read-only property? I tried Const
or Static
but the compiler complains about both.
My class and List:
Public Class Foo
Public Class SampleRating
Enum SampleRateSetting As Byte
SR0 = 1
SR1 = 2
SR2 = 4
SR3 = 8
End Enum
Public Setting As SampleRateSetting
Public Noise As UInt16
Public Bandwidth As UInt16
Public SampleRate As UInt32
Public BinWidth As Double
Public Shared Function FindSetting(Setting As SampleRateSetting) As Predicate(Of SampleRating)
Return Function(Rating As SampleRating) Rating.Setting = Setting
End Function
End Class
Public Shared SampleRatings As New List(Of SampleRating) From {
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR0, .SampleRate = 100189, .BinWidth = 196, .Bandwidth = 26000, .Noise = 467},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR1, .SampleRate = 12524, .BinWidth = 25, .Bandwidth = 6262, .Noise = 260},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR2, .SampleRate = 1566, .BinWidth = 3.1, .Bandwidth = 783, .Noise = 100},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR3, .SampleRate = 196, .BinWidth = 0.38, .Bandwidth = 98, .Noise = 38}
}
' Have also tried the below instead, with no luck
Public Shared SampleRatings As New ReadOnlyCollection(Of SampleRating)(New List(Of SampleRating)() From {
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR0, .SampleRate = 100189, .BinWidth = 196, .Bandwidth = 26000, .Noise = 467},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR1, .SampleRate = 12524, .BinWidth = 25, .Bandwidth = 6262, .Noise = 260},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR2, .SampleRate = 1566, .BinWidth = 3.1, .Bandwidth = 783, .Noise = 100},
New SampleRating With {.Setting = SampleRating.SampleRateSetting.SR3, .SampleRate = 196, .BinWidth = 0.38, .Bandwidth = 98, .Noise = 38}
})
Function Shared Bar() As Boolean
' Should NOT be able to change the list or list item members here.
End Function
End Class 'End of Foo
If you want to make sure the List and the list items are both read only, you'll have to do 2 things.
First, you'll need to use a ReadOnlyCollection instead of a list. Basically, you create your list normally using a standard List object and once it's completed, you can call the AsReadOnly method on your List to get a ReadOnlyCollection.
The second thing you'll have to do is to create read-only properties. Depending on your needs, you may also consider adding a private setter for your property... by definition, it won't be a read-only property, but the setter won't be exposed outside your class so it will prevent any other object from changing the value of your property.
UPDATE
You mentioned that the property should not be modified from the Bar function... The problem here is that you're trying to prevent modifications in SampleRatings
in a class that is also used to initialize the SampleRatings
.
Notice the private setter in the following example. When it's private, you can't initialize the SampleRatings
, but if you make it public, you'll be able to change it in the Bar
function.
Public Class Foo
Public Class SampleRating
Private _noise As UInt16
Public Property Noise() As UInt16
Get
Return _noise
End Get
Private Set(ByVal value As UInt16)
_noise = value
End Set
End Property
End Class
'If the noise is read-only (or has a private setter), you won't be able to set the noise value here...
Public Shared SampleRatings As New ReadOnlyCollection(Of SampleRating)(New List(Of SampleRating)() From {
New SampleRating With {.Noise = 467},
New SampleRating With {.Noise = 260},
New SampleRating With {.Noise = 100},
New SampleRating With {.Noise = 38}
})
Shared Function Bar()
'Doesn't work
SampleRatings.Remove(SampleRatings.First())
'Doesn't work
SampleRatings.First().Noise = 1
End Function
End Class
You didn't mention why you want to prevent modification in your list in the first place... if you want to prevent modification from external assemblies, you should consider declaring your setter as Friend
(see Access Levels in Visual Basic).