Abstract Static Methods in C#: Do They Exist in 2023?


In programming, abstractions are very important.

Abstractions allow us to think in a simpler way when designing software. They help us design software that is easy to understand and extend by other programmers. In C#, abstractions are abstract classes and interfaces. An abstract class can define abstract, virtual, and static methods.

Abstract methods and static methods are key concepts in C# object-oriented programming. However, the unique purposes of both method types make it impossible to have methods declared as ‘static abstract’ in C#.

This article answers why you cannot have abstract static methods in C# and an explanation on C# 11 feature static abstract members in interfaces.

Why can’t I have abstract static methods in C#?

An abstract class is a special class that cannot be instantiated or created any objects from it. The intention of creating an abstract class is to provide a blueprint that defines a set of rules its subclasses must implement whenever they inherit it.

In an abstract class, abstract methods can be declared as ‘abstract’ and do not have any method body or implementation. Instead, you must provide the implementation for the abstract methods only in non-abstract classes or sub-classes that inherit the abstract class. To do that, the subclass must override the abstract methods using the ‘override’ keyword.

On the other hand, a static method is another special method type associated only with a class type. It cannot be overridden by any child classes. This means that a subclass can’t declare the same method but provide a different implementation to it.

If a static method is declared as abstract, then the subclasses that inherit it must provide an implementation for it. However, static methods cannot be overridden, implemented in a subclass, and called using object instances. This is a contradiction between abstract and static method behaviors.

Look at the following example.

abstract class Shape
{
    public static abstract void ShapeColour();
}

According to the rule that you should implement abstract methods in subclasses, what will happen if we implement the static abstract method in the following subclass that inherits it and try to run the program?

class Circle : Shape
{
    public override void ShapeColour()
    {
        Console.WriteLine("Blue");
    }
}

In Visual Studio 2022, .NET 6, the program will throw an error: “A static member cannot be marked as abstract” in the Shape class.

In .NET 7, the program will throw the following errors:

A static member cannot be marked as ‘abstract’

‘Shape.ShapeColour()’ must declare a body because it is not marked abstract, extern, or partial

‘Circle.ShapeColour()’: cannot override inherited member ‘Shape.ShapeColour()’ because it is not marked virtual, abstract, or override

Therefore, these contradictions between static and abstract methods make it impossible to declare a method as static and abstract in C#.

Can abstract classes have static methods?

You can have static methods in abstract classes. If you declare a static method in an abstract class, you must provide its implementation. Static methods are not associated with instances of the class. Therefore, the static method declared in an abstract class should be called using the class name that defined it.

For example, look at the following code that defines a static method in the abstract class Shape.

abstract class Shape
{
    public static int Sum(int x, int y)
    {
        int sum = x + y;
        Console.WriteLine(sum);
        return sum;
    }
}

class Circle : Shape { }

If you try to access the sum method of the abstract class through the instance of the Circle class, the program will throw an error.

Circle c1 = new Circle();
c1.Sum(10, 20);
Console.ReadLine();

Output :

Member’ Shape.Sum(int, int)’ cannot be accessed with an instance reference; qualify it with a type name instead

Thus, using the abstract class name is the right way to call the static method.

Shape.Sum(10,20);

Can abstract classes have static properties?

If a class has private static members, properties are special methods you can use to access those private class members. For example, if a class has a private static int taxRate member, you can declare properties to get and set the value to that private member. Properties can be static. Static properties are the same as static methods.

For example, the following class defines a static property to access the static member’s name in an abstract class.

abstract class Shape
{
    private static string name;

    //static property
    public static string Name
    {
        get
        {
            return name;
        }
        set
        {
            name = value;
        }
    }
}

Usage:

Shape.Name = "Circle";
Console.WriteLine(Shape.Name);

Output : Circle

Can abstract classes have a static constructor in C#?

A constructor is a method that is used to initialize members of a class. You can declare constructors in abstract classes, and sub-classes can call them. But, if you declare a static constructor in an abstract class, it will be executed only once before any static or instance methods.

Following is an example of a static constructor in an abstract class.

class Animal
{
   protected static int numberofLegs;
   
    // The static Constructor
    static Animal()
    {
        Console.WriteLine("Abstract class static constructor\n");
        numberofLegs = 4;
        Console.WriteLine("Animal has four legs");
    }
}

class Cat : Animal
{
    public Cat(){
      Console.WriteLine("Cat Class Constructor");
    }
}

class Dog : Animal
{
    public Dog(){
      Console.WriteLine("Dog Class Constructor");
    }
}

Usage:

Cat c = new Cat();
Dog d = new Dog();

Output:

Abstract class static constructor

Animal has four legs
Cat Class Constructor
Dog Class Constructor

C# 11 feature – static abstract members in interfaces

The static abstract members in the interfaces feature are included in C# as a preview version. The purpose of this feature is to allow you to define interfaces that include overloaded operators or other static members. 

  • For instance, abstracting the ‘zero’ concept in numeric types – double.Zero, int.Zero is abstracted using T.Zero.
  • Operator overloading: double + double, int + int are abstracted using T + T

Also, such interfaces allow you to use their constraints to create generic types that use operators or other static methods.

Following is a simple example of the average operation on double type:

static double avg(double[] arr)
{
    if (arr.Length == 0) { return 0; }
    double sum = 0;
    foreach (var val in arr)
    {
        sum += val;
    }
    return sum / arr.Length;
}

This logic can be abstracted to work on any numeric type like float, int, short, long, etc, only if we can abstract the + operator, / operator, and the concepts of zero and one. With C# abstract static members, now it is possible to do it.

public static class Algorithms
{
    public static T Avg<T>(params T[] arr) where T : IMeasurable<T>
    {

        if (arr.Length == 0) { return T.Zero; }

        T sum = T.Zero;
        T denominator = T.Zero;

        foreach (T val in arr)
        {
            sum = sum + val;
            denominator = denominator + T.One;
        }

        return sum / denominator;
    }
}

Any number type that will implement the IMeasurable interface must define for + and / operators along with One and Zero methods.

public interface IMeasurable<T> where T : IMeasurable<T>
{
    static abstract T operator +(T num1, T num2);
    static abstract T operator /(T num1, T num2);
    static abstract T One { get; }
    static abstract T Zero { get; }
}

Let’s implement the above interface.

public class IntMeasureable : IMeasurable<IntMeasureable>
{
    public int Value { get; set; }

    public IntMeasureable(int value)
    {
        Value = value;
    }

    public static IntMeasureable One => new IntMeasureable(1);

    public static IntMeasureable Zero => new IntMeasureable(0);

    public static IntMeasureable operator +(IntMeasureable num1,
                                            IntMeasureable num2)
    {
        return new IntMeasureable(num1.Value + num2.Value);
    }

    public static IntMeasureable operator /(IntMeasureable num1,
                                            IntMeasureable num2)
    {
        return new IntMeasureable(num1.Value / num2.Value);
    }
}

Finally, use it in the code.

var seven = new IntMeasureable(7);
var fifteen = new IntMeasureable(15);
var eight = new IntMeasureable(8);

var result = Algorithms.Avg(seven, fifteen, eight);

Console.WriteLine(result.Value);

The output of the above example is: 10.

Because of this feature, you can use natural syntax for operators, constant values, and other static operations. Not only that but also, by allowing static methods and operators in interfaces, you can support generic math algorithms.

Conclusion

Abstract and static methods are two important concepts in C# programming. However, while you can declare static methods in abstract classes, you cannot declare abstract static methods in abstract classes in C#.

However, abstract classes can have both static properties and constructors.

The C# feature static abstract members in the interfaces allows you to define interfaces that include overloaded operators or other static members.

Recent Posts