CodeGym /Courses /C# SELF /Static Members in Interfaces

Static Members in Interfaces

C# SELF
Level 24 , Lesson 1
Available

1. Introduction

Back in the day, interfaces were strict, like a private school rulebook: only signatures, no fields, no implementation, no static members! But .NET keeps evolving, and a programming language is like a living thing: to keep up with new challenges, it has to evolve.

With new versions of C#, interfaces have learned some new tricks. One of the most noticeable is static members in interfaces. Turns out, now interfaces can have static methods, properties, and events. In newer versions of C# (starting with C# 11), you can even declare static abstract methods, which require implementing types to provide an implementation.

This is a huge paradigm shift that changes the way we do generic and object-oriented programming.

To put it simply: a static member of an interface is a "shared" member that you access through the interface type itself (or the implementing type), not through an object instance.

Until recently, only classes, structs, and enums could have static methods and properties, but now interfaces can do it too.

What does it look like? Syntax example


public interface IMyMath
{
    static int Add(int a, int b) => a + b; // Static method (default implementation)

    static abstract int Multiply(int a, int b); // Requires implementation in the implementing type 
}
  • static — member is available on the type, not on an instance.
  • static abstract — contracts "require" you to implement a static method in the implementing type.
  • In interfaces (just like in classes), you can now declare static methods, properties, and events. You can also create constants. But interfaces still can't have instance fields or static fields (except constants).

The point of static members in interfaces is to let you declare universal "operations". For example, if you have a collection of objects and want to call "compare" on them without knowing which type implements the interface, you can do it with static abstract members.

2. Static methods with implementation in the interface

Why do we even need this?

Classic problem: you want to describe not just "instance" methods (like, doing something with an object), but also "static" ones (like, creating a new object from a string or comparing two objects in a static way). Before, you had to solve this with patterns (Factory, Comparer, Helper), but now you can express it directly in the interface.

This is especially important for Generics and algorithms that work with arbitrary types:

  • Implementing universal operators (like addition, comparison).
  • Restricting generic code: "Any types that have a static method or operator…"
  • Serialization/deserialization: when you need to create an object from a string without knowing the type at code-writing time.

Static methods with a body

With C# 8, interfaces were allowed to have static methods with a body. They're just like regular static methods in a class.


public interface IUtility
{
    static void PrintHello()
    {
        Console.WriteLine("Hello from Interface!");
    }
}

You can call this method like: IUtility.PrintHello();

This is handy for helper functions that logically belong to the interface, but aren't tied to a specific implementation. For example: stats for all objects of a type, factory methods (CreateDefault), common helper checks (like value validation).

Gotcha: static interface members are not "overridden" in classes

If you declare static void Method() { ... } in an interface, the implementing class can declare a static method with the same signature — but that's not overriding! They're just two independent methods — same name, but not a "virtual static method".

3. Static abstract members

Starting with C# 11, you can declare static abstract methods in interfaces. This means: "every class or struct implementing this interface must declare a static member with the same signature".

Example:


public interface IParsable<T>
{
    static abstract T Parse(string s);
}

Any type implementing this interface must declare a static method Parse(string s).

Implementing such an interface on a class


public class Temperature : IParsable<Temperature>
{
    public int Value { get; set; }

    // Static implementation!
    public static Temperature Parse(string s)
    {
        var temp = new Temperature();
        temp.Value = int.Parse(s);
        return temp;
    }
}

How does it work?

This gets really interesting in generic code:


public static T ParseFromString<T>(string s) where T : IParsable<T>
{
    return T.Parse(s);
}

// Usage:
var temp = ParseFromString<Temperature>("42");

Now you can write truly universal code that works with any types implementing "static" behavior!

4. Static members in interfaces vs. regular static members in classes

Characteristic Static member of a class Static member of an interface
Inherited No No, but implemented as part of the interface contract
Requires implementation No Only if static abstract
Used in Generics No (before C# 11) Yes (with static abstract)
Can have default implementation Yes Yes
Overriding No No, just must be implemented
Visibility when calling Through type name Through interface type or implementing type

7. Real-world examples

Let's see how we can improve our little learning app with these new features.

Say we have an interface "IPrintable":


public interface IPrintable
{
    void Print();
    static void PrintAll(IEnumerable<IPrintable> items)
    {
        foreach (var item in items)
        {
            item.Print();
        }
    }
}

Now you can easily call:


var documents = new List<IPrintable>
{
    new Invoice { Number = "INV-001" },
    new Receipt { Number = "RC-007" }
};
IPrintable.PrintAll(documents); // static method of the interface!

This architecture is great for "group" operations on all implementations of the interface.

More advanced example: generic addition of numeric types

Say we have an interface:


public interface IAddable<T>
{
    static abstract T Add(T left, T right);
}

Implementation for integers (wrapper class):


public struct MyInt : IAddable<MyInt>
{
    public int Value { get; }
    public MyInt(int val) => Value = val;
    public static MyInt Add(MyInt left, MyInt right) => new MyInt(left.Value + right.Value);
}

And finally, a universal function for adding two numbers of type T:


public static T Sum<T>(T a, T b) where T : IAddable<T>
{
    return T.Add(a, b);
}

// Usage:
var x = new MyInt(5);
var y = new MyInt(6);
var z = Sum(x, y); // z.Value == 11

This kind of universality is exactly why static members in interfaces were added!

8. Common mistakes and gotchas

Life with new features isn't always as simple as the examples make it look. Here are a few things that can trip up a newbie:

Static interface methods are not "inherited" by the implementing class. If you declare static void Foo() in the interface, then MyClass.Foo() and IMyInterface.Foo() are two totally different methods.

Static abstract is required to be implemented. If you forget — the compiler will tell you the class doesn't fully implement the interface.

Generic constraints: to use static abstract members, you need to constrain by the interface in the generic parameters (where T : IMyInterface).

Not all tools support the new stuff yet. For example, Rider, VS Code, or old Roslyn analyzers don't always show static abstract members in interfaces correctly if your .NET version doesn't support C# 11+.

Don't confuse with interface extension methods: they're implemented separately and don't work like static members.

2
Task
C# SELF, level 24, lesson 1
Locked
Creating a static method in an interface
Creating a static method in an interface
2
Task
C# SELF, level 24, lesson 1
Locked
Static Method Using an Interface
Static Method Using an Interface
Comments (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
João A Level 54
7 September 2025
this is very confusing to me and didn't get where it's explained: public static T ParseFromString<T>(string s) where T : IParsable<T> {