#714 – Accessibility of a Public Method in an Internal Type

When you declare a class with an accessibility of internal, the class is usable only from code within the same assembly.  If this class then contains a member whose accessibility is public, that member is still limited to an accessibility level of internal.  A member of a class cannot be more accessible than the class itself.

This makes sense.  If we have code that doesn’t know about about a DogCollar class, it certainly can’t invoke the ReportSize method of the DogCollar class.

    // Can only use DogCollar within this assembly
    internal class DogCollar
    {
        // Marked as public, but effectively internal
        public double Size { get; set; }

        public DogCollar(double size)
        {
            Size = size;
        }

        // Also effectively internal
        public void ReportSize()
        {
            Console.WriteLine(string.Format("Collar is {0} in long", Size));
        }
    }
Advertisement

#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");
        }
    }

#620 – Inherit from a Class In A Different Assembly

You can create a new class that inherits from a class that exists in another assembly (e.g. in a class library), as long as the parent class is public (and not sealed).

Let’s assume that someone gives you a copy of DogLibrary.dll, which includes two classes–a Dog class, which is defined as public and a DogMath class, which is defined as internal.

In another program, you can inherit from the Dog class, as long as you add a reference to the DogLibrary assembly.

You inherit from the Dog class just like you inherit from a class within your own program.

    public class Program
    {
        public class CrazyDog : Dog
        {
            public override void Bark()
            {
                Console.WriteLine("Grrrowfffpermuckledoodleweeeheehee!");
            }
        }

        static void Main()
        {
            CrazyDog myDog = new CrazyDog();
            myDog.Bark();
        }
    }

#322 – Class Accessibility

The members of a class all have an associated access modifier, which defines their accessibility.  A class itself also has an accessibility level, which dictates which code can make use of the class.

The two types of accessibility for a class are:

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

In the code below, the Dog class, defined in DogLibrary.dll, is marked as internal.  This means that only code within the same DLL (highlighted blue) can create and use instances of the Dog class.

The Program class in Program.exe has access to the DogKennel class, but not the Dog class.  It can create an instance of a DogKennel, but not an instance of a Dog.

    class Program
    {
        static void Main()
        {
            // Ok
            DogKennel k = new DogKennel();
            k.EverybodyBark();

            // ERROR
            Dog d = new Dog("Kirby");

#305 – Public Class Members

Class members marked with the accessibility keyword public are accessible from any code.

In the picture below, the Dog.DoBark method is marked as public.  The code in any of the blue blocks can call this method.

#303 – Accessibility of Class Members

Members of a class can have different kinds of accessibility.  An accessibility keyword indicates what source code can access the member.  The different types of accessibility are:

Accessibility Keyword Description
public All code can access the member
private Only other code in the class can access the member
protected Code in this class or any class that inherits from this class can access
internal Code in files in the same assembly (.dll or .exe) can access
protected internal Code in the same assembly or in classes that inherit from this class can access

Accessibility keywords can apply to the following kinds of members of a class: fields, properties, methods, constants, indexers, events, constructors and nested types.  They can apply to both instance and static members.

#241 – Declaring and Using Private Instance Methods

You can include a method in a class that is private.  It will be callable from other methods within the class, but not callable from outside the class.

In the example below, the PrintName method is visible from outside the class, but the PrintAge method can only be called from within the class.

    public class Dog
    {
        public string Name;
        public int Age;

        public void PrintName()
        {
            Console.Write(Name);
            PrintAge();
        }

        private void PrintAge()
        {
            Console.WriteLine(string.Format(" ({0})", Age));
        }
    }

Code that attempts to call the PrintAge method from outside the class will not compile.

            Dog kirby = new Dog();
            kirby.Name = "Kirby";
            kirby.Age = 14;

            kirby.PrintName();
            kirby.PrintAge();    // compiler error

#240 – Private and Public Instance Data in a Class

In a class, you can define public instance data, as fields.  Any instance of the class can read and write the instance data stored in these fields.

For example:

    public class Dog
    {
        public string Name;
        public int Age;
    }

    // Creating a Dog object
    Dog kirby = new Dog();
    kirby.Name = "Kirby";
    kirby.Age = 14;

You might, however, want to declare some instance data that is visible from within the class’ methods, but not visible outside the class.  You can do this by declaring a field as private.

        public string Name;
        public int Age;

        private DateTime lastPrint;

        public void PrintName()
        {
            Console.WriteLine(Name);

            // lastPrint is visible here
            lastPrint = DateTime.Now;
        }

This private field will not be visible from outside the class.

            Dog kirby = new Dog();
            kirby.Name = "Kirby";

            // Compiler error: inaccessible due to its protection level
            DateTime when = kirby.lastPrint;