How to Resolve Error "CS0136: A local variable named 'var' cannot be declared in this scope" in C#
The Compiler Error CS0136 is a Variable Shadowing error. The message reads: "A local variable named 'var' cannot be declared in this scope because it would give a different meaning to 'var', which is already used in a 'parent or current/child' scope to denote something else".
C# enforces a strict scoping rule: A variable declared in an inner block (child scope) cannot have the same name as a variable declared in an enclosing block (parent scope).
Unlike C++, where an inner variable "hides" the outer one, C# considers this ambiguous and error-prone. The compiler prevents you from accidentally modifying a local variable when you meant to modify the outer one (or vice versa).
Understanding Block Scope
In C#, scope is generally defined by curly braces { }.
- Parent Scope: The method body.
- Child Scope: Blocks inside the method, such as
if,for,foreach, orusingblocks.
Variables defined in the Parent are visible to the Child. Therefore, the Child cannot define a new variable with the same name, because the name is already taken.
C# vs. C++: In C++, declaring a variable inside an inner block "shadows" (hides) the outer variable. C# explicitly forbids this to prevent logic bugs where developers confuse which variable they are accessing.
Scenario 1: Redeclaration Inside if or loops
This is the most common occurrence. You define a variable at the start of your method, and then accidentally try to define it again inside an if statement.
Example of error
public void ProcessTransaction(bool isConfirmed)
{
int status = 0; // Declared in Parent Scope
if (isConfirmed)
{
// ⛔️ Error CS0136: A local variable named 'status' cannot be declared in this scope
// 'status' is already defined in the parent scope above.
int status = 1;
Console.WriteLine(status);
}
}
Solution: Reuse or Rename
Option A: Reuse (Assign)
If you meant to update the existing variable, remove the int keyword.
public void ProcessTransaction(bool isConfirmed)
{
int status = 0;
if (isConfirmed)
{
// ✅ Correct: Updates the outer variable
status = 1;
}
}
Option B: Rename (Distinct Logic) If the inner variable is logically distinct, give it a new name.
public void ProcessTransaction(bool isConfirmed)
{
int status = 0;
if (isConfirmed)
{
// ✅ Correct: 'innerStatus' is a unique name
int innerStatus = 1;
Console.WriteLine(innerStatus);
}
}
Scenario 2: Nested Loops (The 'i' Conflict)
When copying and pasting loops, it is easy to forget to change the iterator variable (usually i).
Example of error
public void PrintMatrix(int[,] matrix)
{
for (int i = 0; i < 10; i++) // Outer loop uses 'i'
{
// ⛔️ Error CS0136: 'i' cannot be declared in this scope
// The outer 'i' is still visible here.
for (int i = 0; i < 10; i++)
{
Console.WriteLine(matrix[i, i]);
}
}
}
Solution: Use Different Iterators
Standard convention is to use j, k, etc., for nested loops.
public void PrintMatrix(int[,] matrix)
{
for (int i = 0; i < 10; i++)
{
// ✅ Correct: Using 'j' avoids the collision
for (int j = 0; j < 10; j++)
{
Console.WriteLine(matrix[i, j]);
}
}
}
Scenario 3: Lambda Expressions and LINQ
This error frequently appears when using Lambda expressions (=>). The parameters of a lambda expression are local variables within the lambda's scope. If a parameter name conflicts with a local variable outside the lambda, CS0136 is triggered.
Example of error
using System;
using System.Linq;
using System.Collections.Generic;
public class Data
{
public void FilterData()
{
int id = 5; // Local variable
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// ⛔️ Error CS0136: The lambda parameter 'id' conflicts with the local variable 'id'.
var result = numbers.Where(id => id > 0);
}
}
Solution: Rename Lambda Parameter
Change the parameter name in the lambda expression to something generic (like x, n, or item) or specific (num).
public void FilterData()
{
int id = 5;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// ✅ Correct: 'n' does not conflict with 'id'
var result = numbers.Where(n => n > 0);
}
Conclusion
CS0136 is a safety feature of the C# compiler.
- Check Inner Blocks: Look inside your
if,foreach, orwhileblocks. Are you declaring a variable (e.g.,string name) that already exists outside? - Check Iterators: Ensure nested loops use different variables (
i,j,k). - Check Lambdas: Ensure your lambda parameters (
x => ...) don't share names with variables defined right above them.