Access modifiers are something that are confusing at times, and the syntax for them in C# irritates me a little (I wish it worked more like C++). This is a quick Access Modifier summary
There are five types of access modifiers for variables and methods in .Net
1. Public
This is the default for any member of a Struct that isn’t specifically labelled otherwise. A public member is accessable by any caller – hence the name public.
2. Protected
This is more restrictive than public, in fact you can only access members marked Protected if you are inside the class itself or a class that is inheriting the class. Lecturers I had at uni used to espouse the view that you should always use protected instead of private in most situations, as it allows deriving classes to access your classes internals.
With .Net’s excellent support for accessors, i’m not sure if its as necessary to mark internal use storage variables as protected instead of private anymore. In the end, it’s a personal choice.
3. Private
Private variables are completely locked off. The only place they can be accesses are within the class they belong to. This allows accessors and methods to use them (although best practices may suggest even your own methods use accessors instead of directly accessing private variables), but no-one outside the class, not even inheriting classes.
So far, these are the same as is implemented in C++ and Java, however .Net, with its emphasis on assemblies, added two new access modifiers.
4. Internal (friend in visual basic.)
This is similar to private, in that most callers are denied access, however any caller within the same assembly can access members marked this way. This has some interesting side effects, as deriving classes within the assembly treat these members the same as protected (they can access them fine), however derived classes in other assemblies treat this as private, and can’t access it.
5. Protected Internal
Basically combines internal and protected, so that derived classes can access members marked so anywhere, and also callers within the assembly can access without problems.
Personally, i’ve never found a situation so far where i’ve needed the last two. Internal is interesting as it allows you to basically set protected for the members, so your derived classes can use them, but denies this ability to anyone else who derives from your class in another assembly. The down side is, it gives more access to your own classes within the assembly than protected would, so you give up a layer of compartmentability as well.
Theres the quick overview. I’d be very interested to hear of any situations you have come across that required more than private or public, particularly any situations where the two new modifiers were helpful.
–EDIT–
There was a question in the comments about what “const” and “ReadOnly” were, and how they differed. My answer is a bit long and so i’ve added it to this post in full.
This was a bit confusing for me too at first, coming from C++ and Java where we have const, working out what exactly ReadOnly is and, in particular, how it differs from const it difficult.
Const
Const is reasonably easy to explain, it is short for constant. A constant variable is one that is unchanging throughout the life of the application and is used traditionally for literal unchanging values that are used in multiple places throughout your software.
A common example of this is Pi. If you use the value for Pi in several places you can put 3.1415 in different places all through the code, and run the risk of mis-typing it at some point. Or, you can use const float PI = 3.1415 and just use PI throughout the application. Also, if you decide later you want to use a more accurate version, or less accurate version of pi for your calculations, you don’t have to do a search and replace, you can just change it at one place in the code.
Basically, it was a way to mode code easier to read and maintain by labelling literal values.
ReadOnly
ReadOnly looks like it might be Visual Basic only, and is basically a less restrictive version of const. It can be used on variables or properties.
When used on a property, its the same as only setting a get property on a c# property. You can retrieve the value but not set it from outside the class, but if you’re inside you can do what you want to the underlying data type.
When applied to variables, it acts like const. You can set a value in the definition and not change it at any other point during the application. The only exception is a ReadOnly variable that is defined in a class is treated like an ordinary variable whilst inside that class’s constructor. The idea then is you can set a variable to readonly, do some calculations or file reading in the constructor, set the value of the variable, and then, as you leave the constructor, it sets like quick-dry cement and becomes a const variable for the rest of the life of the class.
I hope that helps clear things up, feel free to comment if something is still unclear.