Modifiers

Modifiers in C# are keywords added to class and field declarations (and in some cases enums, interfaces and structs as well). C# supports a wide range of modifiers, and in this post, I will go through some of the advanced modifiers and explaining how they can be used.

The concept of modifiers is in itself not that hard to understand: Most modifiers says something about how you are allowed to use a class or method. While some modifiers forbids you to do something, e.g. inherit from a class marked as sealed, other modifiers permits you to do something, e.g. override a method marked as virtual.

Whether a modifier permits or forbids something is a result of the default state of thing: As a default a class can be inherited from – so we need a modifier to forbid this. And as a default a method cannot be overridden, so a modifier is needed to allow this.

But modifiers can be confusing when more than one modifier is added to the same class or method: Some modifier implicit includes other modifiers: A method marked with the override modifer is implicit virtual, and you are therefore not permitted to add both modifiers. But other modifier explicit requires another modifier – and you have to supply both, e.g. the sealed modifier explicit requires the override modifier.

Enough said, lets get started…

Abstract (class): An abstract class is a class that cannot be instantiated. Thus the only way to use of an abstract class is to use it as a base class. Abstract classes are the opposite of sealed classes, so the two modifiers cannot be used together.

Abstract (method): An abstract method is like a virtual method. But unlike a virtual method which is allowed to be overridden, a abstract method must be overridden. Thus an abstract method contains no implementation (it would always be overridden). This also means that a class containing abstract methods cannot be allowed to be instantiated (the instance would contain empty methods). Thus abstract methods can only exist inside abstract classes. Since an abstract method is already implicit virtual, the virtual modifier cannot be used together with the abstract modifier.

Virtual (class): Do not exists; you cannot override a class, only inherit from it.

Virtual (method): Allows a method to be overridden. Cannot be used together with the private modifier, because if the method is private, it will be impossible to override it. Cannot be used together with the abstract modifier, because a abstract method is already allowed to be overridden. Last, the virtual modifier cannot be used with the override modifier, because overriding methods a implicit virtual.

New (class): Do not exists; you cannot override a class, only inherit from it.

New (method): Provides a new implementation of a base class method to a derived class, and hides the existing method. The base class method must have the same name and signature.

Override (class): Do not exists; you cannot override a class, only inherit from it.

Override (method): Does the same as the new modifier, with a twist Unlike the new modifier, the overridden method in the base class method must be virtual or abstract to be overridden. You can also override methods that them self override some method. This is because a method marked with the override method is implicit marked as virtual.

The difference between new and override modifiers

To understand the difference between overriding and supplying a new implementation, we need an example: We have two classes, the one inheriting from the other. Both classes have the same two methods, but while the derived class replaces the implementation of Method1, it overrides the implementation of Method2.

public class Base
{
    public void Method1()
    {
        Console.WriteLine("Base.Method1");
    }
    public virtual void Method2()
    {
        Console.WriteLine("Base.Method2");
    }
}

public class Derived : Base
{
    public new void Method1()
    {
        Console.WriteLine("Derived.Method1");
    }
    public override void Method2()
    {
        Console.WriteLine("Derived.Method2");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Base b = new Base();
        Derived d = new Derived();
        Base d_in_b = new Derived();
        b.Method1();
        b.Method2();
        d.Method1();
        d.Method2();
        d_in_b.Method1();
        d_in_b.Method2();
    }
}

The difference is that if you mark a method with the new keywork, the base method is still accessible on the derived class – you just have to downcast it to the base . The override keyword overrides the base methods implemetationen, rendering it imposible to used on the derived class – even if a instance of the derived class is casted. This is like the difference between implementation and explicit implementation of an interface, but that is another story.

Sealed (class): A sealed class cannot be inherit, hence a sealed class cannot serve as base class for a derived class.

Sealed (method): A sealed method cannot be overridden. But the sealed modifier can only be used, when overriding an existing method (this is because a ordinary non-overriding method is implicit sealed). Hence the sealed modifier will only make sense together with the override modifier.

Static (class): A static class is a class that cannot be instantiated. But a static class includes methods, that can be used from the type itself. Is a class is static, all its method must be marked a static as well (this will not happens implicit). A static class cannot be inherit from, and is therefore implicit sealed – hence it cannot be marked as either abstract or virtual.

Static (method): A static method is a method that must be used from the type, and not from the instance. A static method is not allowed to interact with instance specific fields.