How to Resolve Error "CS0308: The non-generic type-or-method cannot be used with type arguments" in C#
The Compiler Error CS0308 is a syntax mismatch error. The message reads: "The non-generic type-or-method 'Identifier' cannot be used with type arguments."
In C#, you use angle brackets <T> to supply specific data types to Generic definitions. This error occurs when you try to use this generic syntax on a class, method, or interface that was not defined as generic. Essentially, you are trying to "configure" a type that doesn't accept configuration.
This guide explains how to identify non-generic members and correct the syntax.
Understanding Generic vs. Non-Generic Definitions
- Generic Definition:
public class Box<T> { ... }.- Usage:
var b = new Box<int>();(Correct)
- Usage:
- Non-Generic Definition:
public class Box { ... }.- Usage:
var b = new Box<int>();(Error CS0308)
- Usage:
The compiler looks at the definition of Box. If it doesn't see <T> in the definition, it rejects the usage of <int> in your code.
Scenario 1: Using Generics on Standard Classes
A common mistake is assuming a class is generic when it isn't, often due to similarities with other languages (like Java) or legacy collections.
Example of error
The old ArrayList class is not generic. It stores everything as object.
using System.Collections;
public class Program
{
static void Main()
{
// ⛔️ Error CS0308: The non-generic type 'ArrayList'
// cannot be used with type arguments.
var list = new ArrayList<string>();
}
}
Solution: Use the Generic Alternative
Usually, if you are trying to use generics, you should be using a different class entirely (e.g., switching from System.Collections to System.Collections.Generic).
using System.Collections.Generic; // Different namespace
public class Program
{
static void Main()
{
// ✅ Correct: List<T> is the modern, generic replacement for ArrayList.
var list = new List<string>();
}
}
Scenario 2: Using Generics on Non-Generic Methods
This often happens when using third-party libraries or helper methods. You might expect a method like Parse or Convert to accept a type parameter, but it was designed to be non-generic.
Example of error
public class Parser
{
public object Parse(string input)
{
return input;
}
}
public class Program
{
static void Main()
{
var p = new Parser();
// ⛔️ Error CS0308: 'Parse' is not generic.
// You cannot tell it to parse as '<int>'.
int result = p.Parse<int>("123");
}
}
Solution: Remove Arguments or Cast
If the method isn't generic, use it as is and cast the result, or find a generic alternative if available.
public class Program
{
static void Main()
{
var p = new Parser();
// ✅ Correct: Call the method normally, then cast/convert the result.
int result = Convert.ToInt32(p.Parse("123"));
}
}
Scenario 3: Naming Conflicts (Generic and Non-Generic)
You might have two classes with the same name: one generic, one not. If the compiler resolves the name to the non-generic version (due to using directives), CS0308 occurs.
Example of error
Imagine MyLib.Data (non-generic) and OtherLib.Data<T> (generic).
using MyLib; // Contains class Data
// using OtherLib; // Contains class Data<T> (Missing or shadowed)
public class Program
{
static void Main()
{
// ⛔️ Error CS0308: The compiler thinks you mean 'MyLib.Data'.
// MyLib.Data is not generic.
var d = new Data<int>();
}
}
Solution: Specify the Namespace
Explicitly tell the compiler which class you want.
using MyLib;
using OtherLib;
public class Program
{
static void Main()
{
// ✅ Correct: Fully qualified name resolves the ambiguity.
var d = new OtherLib.Data<int>();
}
}
Conclusion
CS0308 means you are adding configuration (<...>) to something that doesn't support it.
- Check the Definition: Right-click the class or method and choose Go To Definition. Does it have
<T>? - Switch Classes: If using
ArrayList<T>, switch toList<T>. If usingHashtable<K,V>, switch toDictionary<K,V>. - Check Namespaces: Ensure you have imported the namespace that contains the generic version of the class you are looking for.