The var Keyword in C#
By That Developer Guy
(Learn, Build, and Unlock Your Inner Dev)
What is var?
The var
keyword is a way to declare variables without explicitly specifying their type. It's not a type itself—it's an implicitly typed variable where the compiler determines the actual type based on the value you assign.
Important: Despite appearances, var
is not dynamic typing. The variable still has a specific, fixed type determined at compile time. Once declared, you cannot change a var
variable to hold a different type.
var number = 42; // Compiler infers int
var name = "John"; // Compiler infers string
var price = 19.99m; // Compiler infers decimal
var isActive = true; // Compiler infers bool
// number is int - cannot change to string
number = "hello"; // Compile error!
Basic Syntax and Rules
Must Be Initialized
You must assign a value when declaring a var
variable. The compiler needs to know what type to infer.
// Valid - compiler can infer the type
var wholeNumber = 0; // int
var message = "Get Coding"; // string
var percentage = 0.5; // double
// Invalid - compiler cannot infer the type
var name; // Compile error!
name = "John";
// Invalid - cannot infer from null
var value = null; // Compile error!
Equivalent Types
When you use var
, the compiler determines the exact type:
var age = 25;
// Exactly the same as:
int age = 25;
var name = "Get Coding";
// Exactly the same as:
string name = "Get Coding";
var price = 19.99m;
// Exactly the same as:
decimal price = 19.99m;
When to Use var
Good Uses of var
1. When the Type is Obvious
// Type is clear from the right side
var customer = new Customer();
var orders = new List<Order>();
var message = GetWelcomeMessage();
// Obvious from the value
var count = 100;
var name = "John Smith";
var isValid = true;
2. With Complex Generic Types
// Much cleaner with var
var dictionary = new Dictionary<string, List<CustomerOrder>>();
// Compare to explicit type (harder to read)
Dictionary<string, List<CustomerOrder>> dictionary = new Dictionary<string, List<CustomerOrder>>();
3. With Anonymous Types
// Anonymous types REQUIRE var
var person = new { Name = "John", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age}");
4. In LINQ Queries
var query = from customer in customers
where customer.IsActive
select new { customer.Name, customer.Email };
foreach (var item in query)
{
Console.WriteLine($"{item.Name}: {item.Email}");
}
5. In foreach Loops
var numbers = new List<int> { 1, 2, 3, 4, 5 };
foreach (var number in numbers)
{
Console.WriteLine(number);
}
When NOT to Use var
1. When the Type is Not Obvious
// Bad - what type is returned?
var result = ProcessData();
var info = GetCustomerInfo();
// Better - explicit type makes code clearer
Customer result = ProcessData();
CustomerInfo info = GetCustomerInfo();
2. With Numeric Literals (Unless You're Specific)
// This might not be what you want
var number = 5; // int, not short or byte
var price = 19.99; // double, not decimal!
// Better to be explicit
decimal price = 19.99m;
short count = 5;
3. When Type Clarity Aids Understanding
// Unclear what this returns
var data = LoadConfiguration();
// Clear and self-documenting
AppConfiguration data = LoadConfiguration();
Maintainability Benefits
One of the biggest advantages of var
is maintainability when return types change.
Example: Changing Return Types
Original function:
private string GetName()
{
return "Get Coding";
}
static void Main(string[] args)
{
// Explicitly typed - will break if GetName changes
string name1 = GetName();
string name2 = GetName();
string name3 = GetName();
// Using var - adapts to type changes
var name4 = GetName();
}
After changing the return type:
private string[] GetName()
{
return new string[] { "Get Coding" };
}
static void Main(string[] args)
{
// These now cause compile errors - need manual updates
string name1 = GetName(); // Error!
string name2 = GetName(); // Error!
string name3 = GetName(); // Error!
// This automatically adapts to string[]
var name4 = GetName(); // Works without changes
}
This shows how var
can make refactoring easier by automatically adapting to type changes.
Performance
There is NO performance difference between using var
and explicit types. The compiler generates identical code.
var x = 10; // Same performance
int x = 10; // Same performance
// Both compile to identical IL code
The choice between var
and explicit types is purely about code readability and maintainability.
var vs dynamic
Important: Don't confuse var
with dynamic
. They are completely different!
Feature | var | dynamic |
---|---|---|
Type resolution | Compile-time | Runtime |
Type checking | Compile-time | Runtime |
Performance | Same as explicit | Slower (runtime checks) |
IntelliSense | Full support | Limited support |
Type can change | No | Yes |
// var - type determined at compile time
var number = 10; // int
number = "hello"; // Compile error!
// dynamic - type determined at runtime
dynamic value = 10; // int at runtime
value = "hello"; // OK - can change type
value = true; // OK - can change type
Recommendation: Use var
in most cases. Only use dynamic
when you specifically need runtime type resolution (COM interop, reflection scenarios, etc.).
Common Patterns and Examples
Pattern 1: Object Initialization
// Clean and readable
var customer = new Customer
{
Name = "John Smith",
Email = "john@example.com",
IsActive = true
};
Pattern 2: Method Calls
// When the method name clearly indicates the return type
var customers = GetAllCustomers();
var total = CalculateTotal(order);
var settings = LoadAppSettings();
Pattern 3: LINQ Queries
var activeCustomers = customers
.Where(c => c.IsActive)
.OrderBy(c => c.Name)
.ToList();
var summary = orders
.GroupBy(o => o.CustomerId)
.Select(g => new
{
CustomerId = g.Key,
OrderCount = g.Count(),
Total = g.Sum(o => o.Amount)
});
Pattern 4: Tuple Deconstruction
var (name, age, email) = GetPersonDetails();
// Same as:
// (string name, int age, string email) = GetPersonDetails();
Pattern 5: Using with using Statements
using var connection = new SqlConnection(connectionString);
connection.Open();
// Connection automatically disposed at end of scope
Type Inference Examples
Numeric Type Inference
var a = 5; // int
var b = 5L; // long
var c = 5.0; // double
var d = 5.0f; // float
var e = 5.0m; // decimal
var f = (byte)5; // byte
var g = (short)5; // short
Collection Type Inference
var list = new List<int>(); // List<int>
var array = new int[] { 1, 2, 3 }; // int[]
var dict = new Dictionary<string, int>(); // Dictionary<string, int>
Null Handling
// Cannot infer from null alone
var value = null; // Compile error!
// Can infer nullable type
int? nullableInt = null;
var copy = nullableInt; // int?
// Using null-coalescing
var result = GetValue() ?? "default"; // string (if GetValue returns string?)
Best Practices
DO Use var When:
✅ The type is obvious from the right-hand side
var customer = new Customer();
var items = new List<Product>();
✅ Working with anonymous types
var person = new { Name = "John", Age = 30 };
✅ The type name is long or complex
var processor = new DataProcessor<CustomerOrder, InvoiceResult>();
✅ In foreach loops
foreach (var item in collection) { }
DON'T Use var When:
❌ The type is not clear from context
// Bad
var data = GetData();
// Good
CustomerData data = GetData();
❌ You want to enforce a specific numeric type
// Bad - becomes double, not decimal
var price = 19.99;
// Good - explicitly decimal for money
decimal price = 19.99m;
❌ It reduces code clarity
// Bad - what type is result?
var result = ProcessAndTransform(input);
// Good - clear return type
TransformationResult result = ProcessAndTransform(input);
Common Mistakes
Mistake 1: Expecting var to Be Dynamic
var value = 10; // This is int, not dynamic
value = "hello"; // Compile error! Type is fixed
Mistake 2: Not Initializing var
var name; // Compile error!
name = "John";
// Must initialize:
var name = "John"; // OK
Mistake 3: Wrong Numeric Type Inference
var price = 19.99; // This is double, not decimal!
// For money, be explicit:
decimal price = 19.99m;
// Or cast:
var price = 19.99m;
Mistake 4: Using var for Unclear Types
// This makes code harder to understand
var x = Method1();
var y = Method2();
var z = Process(x, y);
// Better with explicit types
Customer x = GetCustomer();
Order y = GetOrder();
Invoice z = ProcessOrder(x, y);
Team Coding Standards
Different teams have different preferences. Here are common approaches:
Approach 1: Always Use var (When Possible)
// Consistency: always use var unless required to be explicit
var count = 0;
var name = "John";
var customer = new Customer();
Approach 2: Use var Only for Obvious Types
// Clear inference
var customer = new Customer();
var items = new List<Product>();
// Not clear - use explicit type
CustomerData data = GetCustomerData();
Approach 3: Use var for Complex Types Only
// Simple types - explicit
int count = 0;
string name = "John";
// Complex types - var
var dictionary = new Dictionary<string, List<Product>>();
Recommendation: Follow your team's coding standards. Consistency is more important than personal preference.
Key Takeaways
var
is not a type—it's implicitly typed at compile time- The compiler infers the exact type from the assigned value
- Must be initialized at declaration
- No performance difference from explicit types
- Great for complex generic types and anonymous types
- Not the same as dynamic—type is fixed after declaration
- Use when type is obvious; avoid when it reduces clarity
- Essential for anonymous types and some LINQ queries
- Makes code more maintainable when return types change
- Follow your team's coding standards for consistency
Next Steps
Now that you understand the var
keyword, explore these related topics:
- Dynamic Type - Runtime type resolution
- Anonymous Types - Using var with anonymous objects
- LINQ - Where var is commonly used
- Type Inference - How the compiler determines types