Skip to main content

How to Resolve Error "CS0718: 'type': static types cannot be used as type arguments" in C#

The Compiler Error CS0718 is a type system error. The message reads: "'StaticClass': static types cannot be used as type arguments".

In C#, Generics (like List<T> or Func<T>) are designed to work with types that can be stored in variables, instantiated, or passed as parameters. A static class, however, creates no objects. You cannot have a variable of type "StaticClass," nor can you create an instance of it (new StaticClass()). Because a static class cannot exist as an object (an instance), it cannot be used as the placeholder T in a generic definition.

This guide explains why static classes are incompatible with generics and how to restructure your code.

Understanding Generics vs. Static Classes

When you declare List<T>, the compiler generates code capable of doing things like:

  • T item; (Declare a variable)
  • item = default(T); (Assign a default value)
  • return item; (Return a value)

If T is a static class:

  • StaticClass item; is illegal syntax.
  • default(StaticClass) is meaningless.
  • You cannot hold a reference to a static class.

Because the fundamental operations of generics rely on T being an instance type (Reference or Value type), static classes are strictly forbidden as type arguments.

Scenario: The Invalid Generic Usage

This error often occurs when a developer tries to create a collection of utility classes, or tries to use a static class as a generic constraint improperly.

Example of error: attempting to create a list of a static helper class.

public static class MathHelpers
{
public static int Add(int a, int b) => a + b;
}

public class Program
{
static void Main()
{
// ⛔️ Error CS0718: 'MathHelpers': static types cannot be used as type arguments.
// A List stores objects. 'MathHelpers' defines no objects.
// You cannot have a "List of Static Classes".
List<MathHelpers> helpers = new List<MathHelpers>();
}
}

Solution 1: Remove the static Keyword

If the class is meant to represent data or a stateful object (an entity), it should not be static.

Solution: change the class to a standard class (and potentially use the Singleton Pattern if you only want one instance).

// ✅ Correct: Removed 'static'
public class MathHelpers
{
public int Add(int a, int b) => a + b;
}

public class Program
{
static void Main()
{
// ✅ Correct: Now we can create instances and store them in a list.
List<MathHelpers> helpers = new List<MathHelpers>();
helpers.Add(new MathHelpers());
}
}

Solution 2: Use Interfaces or Delegates

If you are trying to pass "Functionality" (behavior) rather than "Data" (objects), you shouldn't be passing the static class itself. You should use Interfaces or Delegates.

Option A: Use Delegates (Functions)

If you want to pass the Add method logic to a generic handler, use Func or Action.

public static class MathHelpers
{
public static int Add(int a, int b) => a + b;
}

public class Program
{
static void Main()
{
// ✅ Correct: We aren't passing the class 'MathHelpers'.
// We are passing a reference to the method 'MathHelpers.Add'.
// Func<int, int, int> represents a method taking 2 ints and returning an int.
List<Func<int, int, int>> operations = new List<Func<int, int, int>>();

operations.Add(MathHelpers.Add);
}
}

Option B: Use Generic Constraints Correctly

If you are writing a generic class and want to ensure T has certain static methods, do not try to pass the static class as T. Instead, use Interfaces (and in C# 11+, Static Abstract Members).

// C# 11+ Example
public interface IMath
{
static abstract int Add(int a, int b);
}

// Non-static class implementing the interface
public class StandardMath : IMath
{
public static int Add(int a, int b) => a + b;
}

// Generic class accepts T, not a static class
public class Calculator<T> where T : IMath
{
public int Run(int a, int b) => T.Add(a, b);
}

// Usage: Calculator<StandardMath> (Valid because StandardMath is not static)

Conclusion

CS0718 reminds you that Generics operate on Objects, while Static Classes operate on Global State.

  1. Check the Type: Is the class defined as public static class?
  2. Determine Goal:
    • Need a Collection? If you need a List<T>, T cannot be static. Remove static from the class.
    • Need to Pass Logic? Do not pass the class. Pass the methods inside it using Func<> or Action<>.