Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

C# Dictionary

  1. Home
  2. C# Dictionary
  3. var (Type Inference) (C#)

var (Type Inference) (C#)

In C#, the var keyword lets you declare a local variable without writing the type name explicitly — the compiler infers the type from the expression on the right-hand side. This is static type inference: the type is determined at compile time and never changes at runtime, which is fundamentally different from dynamic typing. var can improve readability when type names are long, but it cannot be used in every context (fields, parameters, return types, etc.).

Syntax

var variableName = value;

// Anonymous types must always be declared with var (they have no named type).
var obj = new { PropertyName1 = value1, PropertyName2 = value2 };

// var requires an initializer at the point of declaration.
// var x; // Compile error: initializer required.
// var x = null; // Compile error: cannot infer type from null alone.

Where var can and cannot be used

Locationvar allowedReason
Local variables (inside a method)YesThe type can be inferred from the right-hand expression.
foreach iteration variableYesThe type is inferred from the element type of the collection.
using declaration / using statementYesThe type can be inferred from the right-hand side.
Class fieldsNoFields can be declared without an initializer, and the compiler may not be able to infer the type.
Method parametersNoType information comes from the caller, so the compiler cannot infer it at the declaration site.
Method return typeNoReturn types must be declared explicitly.
Property typeNoSame reason as class fields.

Sample code

VarBasic.cs
using System;
using System.Collections.Generic;

class VarBasic {
	static void Main() {

		// Even with var, the type is determined statically. The type of the right-hand side becomes the variable's type.
		var name = "item_x"; // Inferred as string.
		var power = 250; // Inferred as int.
		var ratio = 50.0; // Inferred as double.
		var isActive = true; // Inferred as bool.

		Console.WriteLine(name + " score: " + power);
		Console.WriteLine("Multiplier: " + ratio);
		Console.WriteLine("Active: " + isActive);

		// Once inferred, the type is fixed. You cannot assign a value of a different type.
		// power = "string"; // Compile error: cannot assign string to int.

		// Use var instead of writing out Dictionary<string, List<int>> in full.
		var scores = new Dictionary<string, List<int>>();
		scores["item_x"] = new List<int> { 100, 250, 500 };
		scores["item_y"] = new List<int> { 80, 200, 450 };

		foreach (var entry in scores) {
			// entry is inferred as KeyValuePair<string, List<int>>.
			Console.WriteLine(entry.Key + " record count: " + entry.Value.Count);
		}

		var items = new List<string> { "item_x", "item_y", "item_z", "item_w" };

		foreach (var item in items) {
			// item is inferred as string.
			Console.WriteLine("  - " + item);
		}
	}
}

This produces the following output:

dotnet script VarBasic.cs
item_x score: 250
Multiplier: 50
Active: True
item_x record count: 3
item_y record count: 3
  - item_x
  - item_y
  - item_z
  - item_w
VarAnonymousType.cs
using System;

class VarAnonymousType {
	static void Main() {

		// Anonymous types have no name, so there is no way to receive them without var.
		var entry = new {
			Name = "item_x",
			Score = 250,
			Category = "type_a",
			IsActive = true
		};

		Console.WriteLine(entry.Name + " (" + entry.Category + ") score: " + entry.Score);
		Console.WriteLine("Active: " + entry.IsActive);

		// Properties of an anonymous type are read-only; their values cannot be changed.
		// entry.Score = 450; // Compile error: read-only property.

		// If every element has the same structure (property names and types), they can form an array.
		var entries = new[] {
			new { Name = "item_x", Score = 250, Category = "type_a" },
			new { Name = "item_y", Score = 200, Category = "type_a" },
			new { Name = "item_z", Score = 150, Category = "type_b" },
			new { Name = "item_w", Score = 100, Category = "type_c" }
		};

		Console.WriteLine();
		Console.WriteLine("=== Score Ranking ===");

		foreach (var f in entries) {
			// f is inferred as the anonymous type, giving access to Name, Score, and Category.
			Console.WriteLine(f.Name + " (" + f.Category + "): " + f.Score);
		}

		// Project only the properties you need into a new anonymous type.
		// See the Enumerable.Select page for details on LINQ.
		Console.WriteLine();
		Console.WriteLine("=== type_a only ===");

		foreach (var f in entries) {
			if (f.Category == "type_a") {
				// The anonymous type is preserved as-is.
				Console.WriteLine(f.Name + ": score " + f.Score);
			}
		}
	}
}

This produces the following output:

dotnet script VarAnonymousType.cs
item_x (type_a) score: 250
Active: True

=== Score Ranking ===
item_x (type_a): 250
item_y (type_a): 200
item_z (type_b): 150
item_w (type_c): 100

=== type_a only ===
item_x: score 250
item_y: score 200
VarReadability.cs
using System;
using System.Collections.Generic;

class VarReadability {
	static void Main() {

		// Good: the type is obvious from new on the right-hand side, so var aids readability.
		var scores = new Dictionary<string, int>();
		scores["item_x"] = 250;
		scores["item_y"] = 200;
		scores["item_z"] = 500;

		// Good: the iteration variable type is clear from the collection type.
		foreach (var kvp in scores) {
			Console.WriteLine(kvp.Key + ": " + kvp.Value);
		}

		Console.WriteLine();

		// Caution: when the right-hand side is a method call, the return type may not be obvious.
		// var result = GetItemName(); // You have to look up GetItemName() to know the type.
		// string result = GetItemName(); // Writing string explicitly is more readable.

		// Good: when the literal makes the type obvious, var is fine.
		var label = "item_x"; // Clearly a string.
		var level = 250; // Clearly an int.

		// Caution: numeric literals can be ambiguous.
		var ratio = 1.5; // Is it double, float, or decimal? Hard to tell.
		double ratioExplicit = 1.5; // An explicit type makes the intent clearer.

		Console.WriteLine(label + " (level " + level + ") multiplier: " + ratio);

		// The type cannot be inferred from null alone, which causes a compile error.
		// var empty = null; // Compile error.

		// Declare the type explicitly when you need to assign null.
		string emptyName = null;
		Console.WriteLine("emptyName is null: " + (emptyName == null));

		// The following examples are invalid (shown as comments).
		//
		// class Example {
		//     var field = 9000; // Compile error: not allowed for fields.
		//     void Method(var x) { } // Compile error: not allowed for parameters.
		//     var GetValue() { ... } // Compile error: not allowed for return types.
		// }

		Console.WriteLine("Reviewed where var can be used.");
	}
}

This produces the following output:

dotnet script VarReadability.cs
item_x: 250
item_y: 200
item_z: 500

item_x (level 250) multiplier: 1.5
emptyName is null: True
Reviewed where var can be used.

Common Mistakes

Mistaking var for dynamic typing

The type of a variable declared with var is fixed at compile time. Once determined, a value of a different type cannot be assigned. JavaScript's var is dynamically typed and allows the type to change at runtime, but C#'s var is static type inference. They share the same name, which sometimes leads to confusion, but their behavior is fundamentally different.

var count = 10; // Inferred as int.
// count = "text"; // Compile error: cannot assign string to int.

Using var without an initializer

var infers the type from the right-hand expression, so an initializer is required. A bare declaration like var x; or var x = null; causes a compile error. When you need to assign null, declare the variable with an explicit type.

// var x = null; // Compile error: cannot infer type from null alone.
string x = null; // Declaring with an explicit type allows null assignment.

Overview

In C#, var is static type inference: the type is resolved at compile time. This is fundamentally different from dynamic typing (such as JavaScript's var), where the type can change at runtime. Once the type is fixed, you cannot assign a value of a different type to the variable. Use var freely in situations where the type is obvious from the right-hand side — such as instantiation with new or assignment of a literal — to avoid repeating verbose type names.

var is only available for local variables: variables declared inside a method, foreach iteration variables, and using declarations. It cannot be used for class fields, method parameters, or method return types. Declaring a variable without an initializer (var x;) or initializing it with null alone (var x = null;) also causes a compile error because the compiler cannot infer the type.

Anonymous types (new { Name = "item_x", Score = 250 }) have no named type, so the receiving variable must always be declared with var. Properties of an anonymous type are read-only and cannot be changed after initialization. The combination of anonymous types and var appears frequently when projecting only the needed properties in LINQ query expressions.

From a readability standpoint, using var to receive the result of a method call can obscure the return type. When the type is not self-evident, writing it out explicitly makes the code easier for other readers to understand. Following the team's coding conventions to keep var usage consistent is a common approach.

If you find any errors or copyright issues, please .