How to Resolve Error "CS0815: Cannot assign 'expression' to an implicitly typed local" in C#
The Compiler Error CS0815 is a type inference error. The message reads: "Cannot assign 'expression' to an implicitly typed local".
In C#, the var keyword instructs the compiler to infer the variable's type based on the value assigned to it. However, the compiler can only do this if the value on the right-hand side has a distinct, unambiguous type. If you try to assign something that lacks explicit type information—such as null, a lambda expression, or a method group—the compiler cannot determine what type var should represent.
This guide explains the limitations of var and how to fix this error by providing explicit types.
Understanding Type Inference
When you write var x = 10;, the compiler looks at 10, sees it is an int, and compiles the code as int x = 10;.
However, some expressions in C# do not have a type until they are assigned to a specific target.
null: Could be astring,object,int?, or any reference type.x => x + 1: Could beFunc<int, int>,Func<double, double>, orExpression<Func<int, int>>.
Because var asks the expression "What are you?", and these expressions answer "I don't know yet," the compiler raises CS0815.
Scenario 1: Assigning null
This is the most common occurrence. null is a value that can be assigned to any reference type or nullable value type. Without a specific target, null has no type of its own.
Example of error
public void Initialize()
{
// ⛔️ Error CS0815: Cannot assign '<null>' to an implicitly typed local.
// Is 'user' a string? A Person class? An int? The compiler doesn't know.
var user = null;
}
Solution: Explicit Type or Casting
You must tell the compiler what type of variable you are creating.
public void Initialize()
{
// ✅ Correct: Explicitly define the type
string user = null;
// ✅ Correct: Cast the null (if you really want to use var)
var user2 = (string)null;
}
This usually happens when you want to declare a variable to be used later in a try/catch or if/else block. Explicit typing is the standard solution here.
Scenario 2: Assigning Lambda Expressions
Lambda expressions (anonymous functions) are typeless until they are assigned to a Delegate or an Expression Tree. var cannot infer the specific delegate type (like Func or Action) automatically.
Example of error
public void SetupLogic()
{
// ⛔️ Error CS0815: Cannot assign 'lambda expression' to an implicitly typed local.
// This could be Func<int, int>, Predicate<int>, or Expression<...>.
var square = x => x * x;
}
Solution: Define the Delegate Type
Replace var with the specific Func or Action type.
using System;
public void SetupLogic()
{
// ✅ Correct: We tell the compiler this is a Func taking int and returning int.
Func<int, int> square = x => x * x;
// Usage
Console.WriteLine(square(5)); // 25
}
Scenario 3: Assigning Method Groups
A "Method Group" refers to a method name used without parentheses (e.g., Console.WriteLine). Like lambdas, method groups can be assigned to different delegate types depending on the method signature. var cannot choose the delegate type for you.
Example of error
public void SetupLogging()
{
// ⛔️ Error CS0815: Cannot assign 'method group' to an implicitly typed local.
// Console.WriteLine has many overloads. Is this Action<string>? Action<int>?
var logger = System.Console.WriteLine;
}
Solution: Use Explicit Delegate Type
Specify the Action or Func that matches the method signature you intend to use.
using System;
public void SetupLogging()
{
// ✅ Correct: We specifically want the overload that takes a string.
Action<string> logger = Console.WriteLine;
logger("Logging started.");
}
Conclusion
CS0815 is the compiler asking for clarity. var is powerful, but it requires certainty.
- Check the Value: Is the right-hand side
null? If so, use explicit typing (string x = null). - Check Functions: Is the right-hand side a Lambda or Method Name? If so, use
Func<...>orAction<...>. - General Rule: If the compiler can't guess the type, you must write it out.