How to Resolve Error "CS0428: Cannot convert method group 'Identifier' to non-delegate type 'type'" in C#
The Compiler Error CS0428 is a common syntax error that almost always indicates a missing method invocation. The message reads: "Cannot convert method group 'MethodName' to non-delegate type 'int' (or string, object, etc). Did you intend to invoke the method?"
In C#, a Method Group refers to the name of a method (and potentially its overloads) without the parentheses ().
Calculateis a Method Group (represents the function itself).Calculate()is a Method Invocation (runs the function and returns the result).
This error occurs when you try to assign the function itself to a variable that expects the result of the function.
Understanding Method Groups vs. Results
C# allows you to treat methods as values (Delegates), but only if the target variable is a Delegate Type (like Action, Func, or EventHandler).
If the target variable is a "non-delegate type" (like int, string, bool, or var), the compiler assumes you made a mistake. It sees the method name and thinks you are trying to shove the concept of a function into an integer variable.
Scenario 1: Forgetting Parentheses (Most Common)
This happens frequently with methods that look like properties (e.g., ToString, GetType, Count()) or simple getter methods.
Example of error
You want to get the string representation of an object, but you forget the parentheses.
public class User
{
public string GetName() => "Alice";
}
public class Program
{
static void Main()
{
User u = new User();
// ⛔️ Error CS0428: Cannot convert method group 'GetName' to non-delegate type 'string'.
// Did you intend to invoke the method?
// 'u.GetName' refers to the function itself.
string name = u.GetName;
}
}
Solution: Invoke the Method
Add the parentheses () to execute the method and retrieve the return value.
public class Program
{
static void Main()
{
User u = new User();
// ✅ Correct: 'u.GetName()' executes and returns the string "Alice".
string name = u.GetName();
Console.WriteLine(name);
}
}
Properties vs. Methods:
If you find yourself constantly forgetting parentheses for a specific method (like GetName()), consider refactoring it into a Property (public string Name { get; }). Properties are accessed without parentheses.
Scenario 2: Storing the Delegate (Intentional)
Sometimes you do intend to reference the method group because you want to store the function to run it later. However, if you assign it to object or use var without context, the compiler cannot infer which delegate type to create.
Example of error
Trying to store a method in a generic object variable without casting.
public class Calculator
{
public int Add(int a, int b) => a + b;
}
public class Program
{
static void Main()
{
Calculator calc = new Calculator();
// ⛔️ Error CS0428: Cannot convert method group to 'object'.
// The compiler doesn't know if this should be a Func<int,int,int>,
// a custom delegate, or something else.
object func = calc.Add;
}
}
Solution: Cast to a Delegate
If your goal is to store the function pointer, you must cast it to a specific Delegate Type (like Func or Action).
using System;
public class Program
{
static void Main()
{
Calculator calc = new Calculator();
// ✅ Correct: We explicitly tell the compiler to treat 'Add'
// as a function taking 2 ints and returning an int.
Func<int, int, int> func = calc.Add;
// Or explicitly casting if assigning to object:
object funcObj = (Func<int, int, int>)calc.Add;
// We can invoke it later
int result = func(5, 10);
}
}
Conclusion
CS0428 is usually the compiler politely asking: "Did you forget the ()?"
- Check the Line: Look at the method name causing the error.
- Determine Intent:
- Do you want the Result? Add
()to the end of the name. - Do you want the Function? Assign it to a
Func,Action, or explicitdelegatetype, notvarorobject.
- Do you want the Result? Add