How to Resolve Error "CS0112: A static member cannot be marked as override, virtual or abstract" in C#
The Compiler Error CS0112 is a logical contradiction error. The message reads: "A static member 'MemberName' cannot be marked as override, virtual or abstract".
This error occurs because the keywords static and the polymorphism keywords (virtual, abstract, override) represent two fundamentally different behaviors in C#.
- Static members belong to the Class itself. They are resolved at compile-time.
- Virtual/Abstract members belong to an Instance (object). They rely on the runtime type of the object to determine which version of the method to call (Polymorphism).
You cannot mix these concepts. A method cannot be "global to the class" (static) and simultaneously "dependent on the specific object instance" (virtual).
Understanding Static vs. Dynamic Dispatch
- Static: When you call
ClassName.Method(), the compiler knows exactly which code to run because the method is tied to the class name. There is no lookup table. - Virtual/Override: When you call
object.Method(), the runtime checks the actual type of the object in memory to decide whether to run the base implementation or an overridden version.
Since static calls don't use an object instance, there is no "vtable" (virtual table) lookup, and thus no mechanism to support overriding.
Scenario 1: Trying to Make Static Methods Virtual
A common mistake is trying to define a "Static Contract"—for example, trying to force all derived classes to have a specific static factory method.
Example of error
public class BaseEntity
{
// ⛔️ Error CS0112: A static member cannot be marked as virtual
// The compiler logic: "How can I override this if I call it via BaseEntity.Create()?"
public static virtual void Create()
{
System.Console.WriteLine("Base Create");
}
}
Solution
In C# (prior to C# 11), you cannot enforce static methods in inheritance.
- Option A: Make it an Instance method (remove
static). - Option B (C# 11+): Use Static Abstract Members in Interfaces.
C# 11+ Solution (Interfaces):
public interface IEntity
{
// ✅ Correct: C# 11 allows static abstract in interfaces ONLY
static abstract void Create();
}
public class User : IEntity
{
public static void Create() => System.Console.WriteLine("User Created");
}
Scenario 2: Trying to Override in a Static Context
You might try to override a base class method but accidentally mark the child method as static, or try to override a static method from the parent.
Example of error
public class Parent
{
public virtual void Show() { }
}
public class Child : Parent
{
// ⛔️ Error CS0112: 'override' requires dynamic dispatch.
// 'static' removes dynamic dispatch. They cannot coexist.
public static override void Show()
{
// ...
}
}
Solution
Decide if you want polymorphism or a utility method.
public class Child : Parent
{
// ✅ Correct: Polymorphism (Instance method)
public override void Show() { }
}
Solution: Use Instance Methods or Hiding
If you genuinely need a static method in the child class with the same name as the parent (but not utilizing polymorphism), you are looking for Method Hiding, not overriding.
Method Hiding with new
You can declare a static method in the child class that "hides" a method in the parent. This allows you to use the same name, but the methods are technically unrelated.
public class Parent
{
public static void Log() => System.Console.WriteLine("Parent Log");
}
public class Child : Parent
{
// ✅ Correct: The 'new' keyword allows us to reuse the name 'Log'.
// Note: This is NOT overriding.
// Parent.Log() calls Parent.
// Child.Log() calls Child.
public static new void Log() => System.Console.WriteLine("Child Log");
}
Conclusion
CS0112 prevents you from combining contradictory language features.
- Check Keywords: Scan your method signature. Do you see
staticAND (virtual,abstract, oroverride)? - Choose One:
- If you want Inheritance/Polymorphism: Remove
static. - If you want a Global/Utility Method: Remove
virtual/override.
- If you want Inheritance/Polymorphism: Remove
- Modern C#: If you are trying to define a contract for static factory methods, look into C# 11 Static Abstract Interface Members.