Question

If I set a Friend-level scope on a setter, like this...

Public Class MyClass
    Public Property IsDirty() As Boolean
        Get
            Return _isDirty
        End Get
        Friend Set(ByVal trueFalse As Boolean)
            _isDirty = trueFalse
        End Set
    End  Property
End Class

...And then call it from another project, it works correctly. I can't do something like MyClass.IsDirty = True.

Great! That's exactly what I want.

But now if I define an interface, and I will indeed have to do that:

Public Interface IMyClass
    Property IsDirty() As Boolean
End Interface

I can do something like:

Dim MyInstance as IMyClass= GetSomeInstanceOfMyClass()
MyInstance.IsDirty=True

...And, bizarrely, it runs! No exceptions are thrown, and the inner variable is set to True. It ignores the Friend scope completely!

That's hideous. What am I missing??

Note: I need this because I'm designing an API, and I want the inner API to be able to set IsDirty, but end-developers shouldn't be able to get into that. Currently I am wrapping the whole class in a facade to get this functionality, but the facade should be unecessary.

Was it helpful?

Solution

Interface methods always have public accessibility. You can't fix that by explicit interface implementation, that will only hide the class method. Simply casting the object to the interface type gives unfettered access again.

EDIT: actually, the problem is easy to solve. Just declare the property ReadOnly in the interface declaration :)

For example:

Public Interface IMyClass
    ReadOnly Property IsDirty() As Boolean
End Interface

Public Class Test
    Implements IMyClass
    Private mIsDirty As Boolean
    Private ReadOnly Property IsDirtyImpl() As Boolean Implements IMyClass.IsDirty
        Get
            Return mIsDirty
        End Get
    End Property
    Public Property IsDirty() As Boolean
        Get
            Return mIsDirty
        End Get
        Friend Set(ByVal value As Boolean)
            mIsDirty = value
        End Set
    End Property
End Class

OTHER TIPS

What you are missing is the concept of inplicit and explicit interface implementation. See the answer to this question for more details.

And if you think it's hideous with a Friend setter, try setting it to Private and watch it still be accessible via the interface!

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