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<>.