Looks like the answer from the other question will work: here's a sample:
Public Interface IReadOnly
ReadOnly Property Name() As String
End Interface
Public Interface IReadWrite
Inherits IReadOnly
Overloads Property Name() As String
End Interface
Public Class ReadOnlyClass
Implements IReadOnly
Private _Name
Public ReadOnly Property Name() As String Implements IReadOnly.Name
Get
Return _Name
End Get
End Property
End Class
Public Class ReadWriteClass
Implements IReadWrite
Private ReadOnly Property ReadOnly_Name() As String Implements IReadOnly.Name
Get
Return Name
End Get
End Property
Private _Name As String
Public Overloads Property Name() As String Implements IReadWrite.Name
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
End Class
The above approach will actually result in classes that implement IReadWrite also implementing IReadOnly--so you'll actually need to downcast to IReadWrite in order to set the property.
Another approach, which avoids that issue but requires a little more logic in the implementing classes and their caller's is something like:
Public Interface ISometimesWritable
Property Name() As String
ReadOnly Property AllowNameEdit() As Boolean
End Interface
Public Class ReadOnlyClass
Implements ISometimesWritable
Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit
Get
Return False
End Get
End Property
Private _Name As String
Public Property Name() As String Implements ISometimesWritable.Name
Get
Return _Name
End Get
Set(ByVal value As String)
Throw New NotSupportedException("Name cannot be set when AllowNameEdit is False")
End Set
End Property
End Class
Public Class ReadWriteClass
Implements ISometimesWritable
Public ReadOnly Property AllowNameEdit() As Boolean Implements ISometimesWritable.AllowNameEdit
Get
Return True
End Get
End Property
Private _Name As String
Public Property Name() As String Implements ISometimesWritable.Name
Get
Return _Name
End Get
Set(ByVal value As String)
_Name = value
End Set
End Property
End Class
Update: To answer the question about downcasting; "downcasting" is a term used to describe casting an object from a superclass, interface, or abstract base class Type
into a more concrete Type
.
For example, the first example above defines two interfaces: IReadOnly
and IReadWrite
. You'll notice that IReadWrite
implements IReadOnly
, which means that you can make both IReadWrite
and IReadOnly
calls to objects which implement IReadWrite
.
Since IReadWrite
implements IReadOnly
, IReadWrite
is said to be a "sub-class" of IReadOnly
(although "sub-class" is more accurately used to describe a class which inherits a base class, rather then implements an interface--for the sake of simplicity they are very nearly the same concept). If IReadWrite
is a sub-class of IReadOnly
, then the inverse is true--IReadOnly
is a super-class of IReadWrite
.
For example, I can describe an instance of ReadWriteClass
as an implementation of either interface:
Public Sub SomeMethod()
dim readOnlyInstance as IReadOnly = new ReadWriteClass()
Console.WriteLine(readOnlyInstance.Name)
' The following line won't compile, since we're communicating with ReadWriteClass as an instance of IReadOnly
'readOnlyInstance.Name = "Santa Clause"
' Here we downcast the variable to reference it by it's other interface, IReadWrite
dim readWriteInstance = DirectCast(readOnlyInstance, IReadWrite)
' Now we can both Get and Set the value of Name
readWriteInstance.Name = "John Doe"
Console.WriteLine(readWriteInstance.Name)
' Note that in the above example we created *one* instance of ReadWriteClass
' and have provided two variables / references to the same underlying object.
Console.WriteLine(readOnlyInstance.Name) ' <-- note that this should return "John Doe"
End Sub