News & UpdatesProgrammingWeb programming StoreMy Projects
Links
Affiliates

C# Tutorial – 14 – Access Levels

Every class member has an accessibility level that determines where the member will be visible. There are five of them available in C#: public, protected, internal, protected internal and private. The default access level for members of a class is private.

Private access

All members regardless of access level are accessible in the class in which they are declared, the enclosing class. This is the only place where a private member can be accessed.

class MyBase
{
  // Unrestricted access
  public int myPublic;
 
  // Defining assembly or derived class
  protected internal int myProtInt;
 
  // Defining assembly
  internal int myInternal;
 
  // Defining or derived class
  protected int myProtected;
 
  // Defining class only
  private int myPrivate;
 
  void Test()
  {
    myPublic    = 0; // allowed
    myProtInt   = 0; // allowed
    myInternal  = 0; // allowed
    myProtected = 0; // allowed
    myPrivate   = 0; // allowed
  }
}

Protected access

A protected member can also be accessed from within a derived class, but it is inaccessible from other classes.

class Derived : MyBase
{
  void Test()
  {
    myPublic    = 0; // allowed
    myProtInt   = 0; // allowed
    myInternal  = 0; // allowed
    myProtected = 0; // allowed
    myPrivate   = 0; // inaccessible    
  }
}

Internal access

An internal member can be accessed anywhere within the local assembly, but not from another assembly. In .NET, an assembly is either a program (.exe) or a library (.dll).

// Defining assembly
class AnyClass
{
  void Test(MyBase m)
  {
    m.myPublic    = 0; // allowed
    m.myProtInt   = 0; // allowed
    m.myInternal  = 0; // allowed
    m.myProtected = 0; // inaccessible
    m.myPrivate   = 0; // inaccessible
  }
}

Protected internal access

Protected internal access means either protected or internal. A protected internal member can therefore be accessed anywhere within the current assembly, or in classes outside the assembly that are derived from the enclosing class.

// Other assembly
class Derived : MyBase
{
  void Test(MyBase m)
  {
    m.myPublic    = 0; // allowed
    m.myProtInt   = 0; // allowed
    m.myInternal  = 0; // inaccessible
    m.myProtected = 0; // allowed
    m.myPrivate   = 0; // inaccessible
  }
}

Public access

Public access gives unrestricted access from anywhere that the member can be referenced.

// Other assembly
class AnyClass
{
  void Test(MyBase m)
  {
    m.myPublic    = 0; // allowed
    m.myProtInt   = 0; // inaccessible
    m.myInternal  = 0; // inaccessible
    m.myProtected = 0; // inaccessible
    m.myPrivate   = 0; // inaccessible
  }
}

Top-level access levels

A top-level member is a type that is declared outside of any other types. In C#, the following types can be declared on the top-level: class, interface, struct, enum and delegate. By default, these uncontained members are given internal access. To be able to use a top-level member from another assembly the members have to be marked as public. This is the only other access level allowed for top-level members.

internal class MyInternalClass {}
public class MyPublicClass {}

Inner classes

Classes may contain inner classes, which can be set to either one of the five access levels. The access levels have the same effect on inner classes as they do on other members. If the class is inaccessible, it cannot be instantiated or inherited. By default, inner classes are private, which means that they can only be used within the class where they are defined.

class MyBase
{
  // Inner classes (nested classes)
  public    class MyPublic {}
  protected internal class MyProtInt {}
  internal  class MyInternal {}
  protected class MyProtected {}
  private   class MyPrivate {}
}

Access level guideline

As a guideline, when choosing an access level it is generally best to use the most restrictive level possible. This is because the more places a member can be accessed the more places it can be accessed incorrectly, which makes the code harder to debug. Using restrictive access levels will also make it easier to modify the class without breaking the code for any other programmers using that class.