How to Resolve Error "CS0307: The 'construct' 'identifier' is not a generic method" in C#
The Compiler Error CS0307 is a syntax error related to Generics. The message reads: "The property 'Name' (or field/variable) is not a generic method. If you intended an expression list, use parentheses around the < expression."
In C#, angle brackets <T> are used to supply type arguments to Generic Methods or Generic Classes. This error occurs when you apply these brackets to a member that does not support them, such as a Property, a Field, or a Variable. Essentially, you are trying to "configure" a type for something that is just a simple value.
This guide explains why this syntax mismatch occurs and how to correct it.
Understanding Generic Syntax
Generic syntax allows you to specify types for methods that are designed to handle various data types.
- Valid:
myList.Select<int>(...)(Select is a generic method). - Invalid:
myList.Count<int>(Count is a property, simply an integer).
When the compiler sees identifier<T>, it expects identifier to be a method defined like void Method<T>(). If identifier is actually a property (like List.Count), the compiler gets confused. It tells you it's "not a generic method" and suggests you might be trying to do a "Less Than" comparison (e.g., Count < 5), hence the confusing advice about "expression lists."
Scenario 1: Using Generics on Properties
This is the most common cause. Developers often get used to LINQ syntax (like .Select<T>() or .Cast<T>()) and accidentally apply the same syntax to standard properties like .Count or .Length.
Example of error
Attempting to specify a type for the Count property of a list.
using System.Collections.Generic;
public class Program
{
static void Main()
{
List<string> names = new List<string> { "Alice", "Bob" };
// ⛔️ Error CS0307: The property 'List<string>.Count' is not a generic method.
// 'Count' is just an integer. It doesn't need to know about 'int' or 'string'.
int count = names.Count<int>();
}
}
Solution: Remove Type Arguments
Properties are values, not methods. Simply access the property name.
using System.Collections.Generic;
public class Program
{
static void Main()
{
List<string> names = new List<string> { "Alice", "Bob" };
// ✅ Correct: Just access the property.
int count = names.Count;
System.Console.WriteLine(count);
}
}
Why the error mentions "expression list":
The compiler sees names.Count < int. It thinks you might be trying to check if names.Count is less than a variable named int. Since int is a type, this logic falls apart, resulting in the confusing suggestion to use parentheses.
Scenario 2: Using Generics on Non-Generic Methods
You might try to pass a type argument to a method that looks like it should be generic, but isn't. This often happens with older libraries or methods that operate on object.
Example of error
The ToString() method exists on every object, but it is not generic.
public class Data
{
public int Id { get; set; }
}
public class Program
{
static void Main()
{
var d = new Data();
// ⛔️ Error CS0307: The method 'ToString' is not a generic method.
// You cannot customize ToString by passing a type.
string s = d.ToString<string>();
}
}
Solution: Remove Brackets
Use the method as defined.
public class Program
{
static void Main()
{
var d = new Data();
// ✅ Correct: Standard method call
string s = d.ToString();
}
}
Conclusion
CS0307 is a syntax error indicating misplaced angle brackets < >.
- Check the Member: Hover over the identifier (e.g.,
Count,ToString). - Is it a Property? Properties never take type arguments. Remove
<T>. - Is it a Method? Check the definition. If it is defined as
void Method(), you cannot call it asMethod<T>(). Remove<T>.