Two Cents On Access Modifiers in C#

Access modifiers, as their name suggests, control who sees what in an application. C# has 4 basic access modifiers (thereâs also a 5th one, but more on that later). Here they are, listed from least restrictive to most restrictve.
public: accessible anywhere.protected: accessible to current class and all derived classes.internal: accessible to any class in the current assembly.private: accessible to current class only.
Easy enough to understand.
Some Things to Keep In With Access Modifiers
- Namespaces canât have access modifiers. Theyâre always public. So:
public namespace AwesomeNewNamespace { ⦠}will produce a compile-time error. - Classes can be either public or internal but not protected or private. So:
private class AwesomeNewClass { ⦠}will produce a compile-time error. This makes sense if you think about it â how exactly would you use a private or a protected class?? - Interfaces, like classes, can be either public or internal but not protected or private.
- Methods defined in interfaces canât have access modifiers.
- Enums are always public. They canât have access modifiers either.
- By default, classes are internal. So:
class NotSoCool { ⦠}is equivalent tointernal class NotSoCool { ⦠}. - By default, methods in class are private. So
void SomeAwesomeMethod() { ⦠}is equivalent toprivate void SomeAwesomeMethod() { ⦠}. - Same goes for variables (fields): private unless specified otherwise.
- Needless to say, you canât use access modifiers on variables inside a method:
public voidMethod() { protected string someString;will produce a compile-time error. - Derived classes can either have the same restriction level or can be more restrictive than the base class but not less restrictive. So:
internal class Base { ⦠} public class Child : Base { }will produce a compile-time error.
Now that we got that out of the way, letâs take a look at that 5th modifier that I mentioned at the beginning. This would be the compound modifier protected internal. After looking at it for a minute, you would think that it does what other compound modifiers in .NET do. For example, protected virtual void AwesomeMethod() makes AwesomeMethod both virtual and protected, so youâd think that protected internal AwesomeClass { ⦠} would make the class both protected and internal (i.e., it is only accessible to derived classes in the assembly) but you would be wrong. For some bizarre reason that I have yet to fathom, the powers-to-be have decided that protected internal means protected or internal (so that the method is available to all derived classes as well as all classes in the current assembly).
