#713 – Declare Accessibility Explicitly

It’s always good practice to explicitly declare the accessibility of an item, for class members, struct members, and classes.  Declaring the accessibility makes it clear what the accessibility is for the item and avoids someone having to recall what the default accessibility is.

    public class Dog
    {
        // Stuff that's clearly public
        public string Name { get; set; }
        public int Age { get; set; }

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Stuff that's clearly private
        private int numBarks;

        // Not obvious--private or public?
        //   (private, because class members are private by default)
        void DoBark()
        {
            Console.WriteLine("WOOF");
        }
    }
Advertisements

#712 – Accessibility Summary

Namespaces, types, class members, struct member, interface members and enumeration members all have an associated accessibility, dictated by the access modifer included in the member’s declaration.

The possible levels of accessibility are:

  • public – all code can access member
  • private – only code within the same type can access member
  • protected – code within type or subtype can access member
  • internal – code within the same assembly can access member
  • protected internal – code within the same assembly, within the same type, or within a subtype can access member

The type of member dictates which levels of accessibility are allowed:

  • class – can be public or internal  (default is internal)  [can only be public if parent class is public]
  • namespace – always public
  • class members – can be public, private, protected, internal or protected internal  (default is private)
  • struct members – can be public, private, or internal (default is private)
  • interface members – always public
  • enumeration members – always public

#699 – Types Are Implicitly Internal

When you define a type in C#, you can define its accessibility as either public or internal.  Public types are visible to all code.  Internal types are visible only to code within the same assembly.

By default, if you don’t include an access modifier when defining a type, the type’s accessibility will be internal.

In the example below, the Dog class will be visible only to code within the same assembly.

    // No access modifier => type is internal, visible
    //   only to code within the same assembly.
    class Dog
    {
        // Public properties
        public string Name { get; set; }
        public int Age { get; set; }

        // Instance constructor
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public void Bark()
        {
            Console.WriteLine("Woof");
        }
    }

#698 – Type Members Are Implicitly Private

You use access modifiers to define the accessibility of members within a class (publicprivate, protected, internal or protected internal).

If you omit the access modifier entirely, the class member defaults to being private.  This is true for all class members, including constants, fields, properties, methods, indexers, events, constructors and nested types.

In the example below, the Description property, NumDogs static property and the ChaseTail method are all effectively private members, because their declaration does not include an access modifier.

    public class Dog
    {
        // Public properties
        public string Name { get; set; }
        public int Age { get; set; }

        // Implicitly private
        string Description { get; set; }

        // Instance constructor
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Implicitly private
        static int NumDogs { get; set; }

        // Implicitly private
        void ChaseTail()
        {
            Console.WriteLine("I'm chasing my tail");
        }
    }

#627 – Accessibility of Nested Types in a struct or a class

When you define a type within the scope of a class (a nested type), the accessibility of the nested type can be one of the following

  • public
  • protected internal
  • protected
  • internal
  • private  (default)

When you define a type within a struct, the choices for accessibility of the nested type are more limited and include:

  • public
  • internal
  • private  (default)

Remember that the outer type (the class or struct) has more limited accessibility choices:

  • public
  • internal  (default)

#624 – Accessibility of a Nested Class

When you define one class within the scope of another (a nested class), you have several choices for the accessibility of the inner class.  The inner class can be defined with any of the following access modifiers:

  • public – the class is accessible from any code, within the assembly where it’s defined or from a different assembly
  • protected internal – class accessible from any subclass of the outer class or from any code within the same assembly
  • protected – class accessible from any subclass of the outer class
  • internal – class accessible from any code within the same assembly
  • private – class accessible only from within the outer class

Notice that the choices for accessibility of a nested class are much broader than for a class defined in a standard namespace scope (public, internal).

#614 – Subclass Accessibility

A class can be defined with one of two different levels of accessibility:

  • public – all code can use the class
  • internal – only code in the same .exe or .dll can use the class

When you define a subclass, the accessibility of the subclass must be the same as, or less accessible than, the parent class.

This means:

  • If the parent class is public
    • Subclass can be public or internal
  • If the parent class is internal
    • Subclass must be internal