This rule is described in detail in Effective C#: 50 Specific Ways to Improve your C#.
Explicitly typing local variables when the type can be inferred from the initialization expression.
Using implicitly typed local variables (declared with var
) can enhance code readability and maintainability by focusing on the variable's semantic meaning rather than its type. It also allows the compiler to choose the best type, reducing potential type conversion issues and errors. However, for built-in numeric types (int, float, double, etc.), it is recommended to use explicit typing to prevent unintended type conversions and maintain precision.
Replace explicitly typed local variable declarations with var
when the type can be inferred from the initialization expression. For built-in numeric types, retain explicit type declarations.
Suppress warnings if explicit typing is necessary for clarity, especially when the type is not easily inferred from the initialization expression, or when dealing with built-in numeric types where precision and conversion issues are not a concern.
Problems caused by implicitly typed locals when you delcare variables of built-in numeric types can occur. There are numerous conversions between the built-in numeric types. Widening conversions, such as from float to double, are always safe. There are also narrowing conversions, such as from long to int, that involve a loss of precision. By explicitly declaring the types of all numeric variables, you retain some control over the types used, and you help the compiler warn you about possible dangerious conversions.
var f = GetMagicNumber();
var total = 100 * f / 6;
Console.WriteLine($"Declared Type:{total.GetType().Name}, Value:{total}");
double GetMagicNumber() => 100.0;
There are five outputs to the code example depending on the type returned from GetMagicNumber()
. Here are five outputs:
Declared Type: Double, Value = 166.666666666667 Declared Type: Single, Value = 166.6667 Declared Type: Decimal, Value = 166.66666666666666666666666667 Declared Type: Int32, Value = 166 Declared Type: Int64, Value = 166
The differences in the type are caused by the way the compiler infers the type of f
, which modifies the inferred type of total
.
Use var
to allow the compiler to infer the type of the local variable.
double f = GetMagicNumber();
double total = 100 * f / 6;
Console.WriteLine($"Declared Type:{total.GetType().Name}, Value:{total}");
double GetMagicNumber() => 100.0;