I've encountered a problem which challenges my understanding of access modifiers in VB.Net. I have a class declared Friend. If I declare its properties Public, the application works. If I declare them Friend, the application fails.
Before this, I believed that, in a class declared Friend, it would make no functional difference whether I declared the members Public or Friend. I thought class access declarations applied their restrictions to all nested entities, so nested properties declared Public were effectively restricted as if they had been declared Friend. Obviously, I was wrong. Can anyone explain how access modifiers really work, or point me to the relevant documentation?
Here is a more detailed description of the situation: I have a Friend class called StripTask with properties called StripDate, HistorianDate, and TaskText. I have a collection of StripTasks (called _StripTasks) which is used as the data source for a Syncfusion GridDataBoundGrid. The way the binding works, I need to pass the name of a StripTask property to each of the grid columns so each column knows what data to display. It ends up looking something like this: _DataBoundGrid.GridBoundColumns(1).MappingName = "StripDate". When the mapped properties are declared Public, it works. When the mapped properties are declared Friend, the grid is populated with the correct number of rows, but every cell is empty.
As a follow-up question, is it a good idea to avoid things, such as this Syncfusion binding method, which require me to pass property names as strings? It just feels as if I'm inviting trouble.
No, the access level of a class does not trickle down to the members and methods. In VB all methods are
Public
if you don't specify anything. If you mark something asFriend
you are saying that you don't want code outside of your assembly to be able to access it which sounds exactly like what you are seeing.EDIT
What's important to understand is that access rules at the class level deal mostly with instantiation and typing. Imagine the following DLL that uses reflection to look at a given object's properties (which is almost definitely what Syncfusion does):
Then imagine the following WinForms app in a separate assembly with a reference to the above DLL:
You can pass both a
Friend
class as well as aPrivate
class to another assembly, that's completely valid. However, on the other side the DLL won't be able to access theFriend
orPrivate
properties, only thePublic
one. When this is run you'll see two lines in the Immediate window withPublicProp
which is the only property that it can see.