Q: I’m confused about what some of the .NET access modifiers mean and when I should use them. Can you help me sort them out?

A: Well, I’ll certainly try. The allowed access modifiers in .NET are public, private, protected, internal, and protected internal. These keywords control the visibility of class members (and other things), defining the circumstances under which a member may be accessed—hence their collective name as access modifiers. With the exception of the last, protected internal, it’s illegal to combine two access modifiers. Let’s look at what each of these mean in turn when used in a .NET class.

Access modifiers illustrated
Public means just that: public and visible to everyone and everything. A public member can be accessed using an instance of a class, by a class’s internal code, and by any descendants of a class. This is illustrated in Figure A.

Figure A
A public class member

Private is also intuitively understood, meaning hidden and usable only by the class itself. No code using a class instance can successfully access a private member and neither can a descendant class, as illustrated in Figure B. Information or functionality that will not be needed or has no meaning outside of the context of a specific class should be made private.

Figure B
A private class member

Protected members are similar to private ones in that they are accessible only by the containing class. However, protected members also may be used by a descendant class. So members that are likely to be needed by a descendant class should be marked protected, as Figure C shows.

Figure C
A protected class member

Members marked as internal are public to the entire application but private to any outside applications. Internal is useful when you want to allow a class to be used by other applications but reserve special functionality for the application that contains the class. Figure D illustrates internal in action.

Figure D
An internal class member

Finally, we have the only compound access modifier allowed in .NET, protected internal, which is shown in Figure E. Members marked as protected internal may be accessed only by a descendant class that’s contained in the same application as its base class. You use protected internal in situations where you want to deny access to parts of a class’ functionality to any descendant classes found in other applications.

Figure E
A protected internal class member

Not limited to controlling class access
As I mentioned before, access modifiers aren’t limited to use on class members but can be applied to a few other code constructs. The rules defining when modifiers may be legally assigned to a construct are dependant on the construct’s container:

  • Interface and enumeration members are always public and no access modifiers are needed (or allowed).
  • Classes in namespaces are internal by default and may be either internal or public, while namespaces themselves are always public.
  • Members of a struct are private by default and may be given public, internal, or private access modifiers.

In all cases, however, the modifier’s meaning remains the same.