Concepto · tipos

var frente a tipos explícitos en C#

El malentendido más común: var no es tipado dinámico. La variable sigue teniendo exactamente un tipo, elegido por el compilador a partir del lado derecho — simplemente no lo escribiste tú.

Qué hace realmente var

El tipo sale del lado derecho, en tiempo de compilación. En Visual Studio este programa imprime los tipos — y nunca cambian después:

var precio = 9.99;        // double — porque 9.99 es un literal double
var cantidad = 42;        // int    — porque 42 es un literal int
var nombre = "Ada";       // string

Console.WriteLine(precio.GetType());   // System.Double
Console.WriteLine(cantidad.GetType()); // System.Int32
Console.WriteLine(nombre.GetType());   // System.String

(La reflexión .GetType() no está en el subconjunto del motor — las afirmaciones de abajo se verifican con comprobaciones que sí se ejecutan aquí.)

El chequeo estricto de tipos del motor demuestra lo mismo en vivo — una variable var se comporta exactamente como su tipo inferido:

var x = 9.99;   // x es double desde esta línea
int y = x;      // CS0266: exactamente como si hubieras escrito 'double x = 9.99;'

Si var fuera dinámico (como en JavaScript), esa asignación habría compilado. No lo hizo — porque x es un double en todos los sentidos, solo que inferido.

Dos trampas de literales que conviene conocer antes del día uno

var a = 7 / 2.0;    // double: 3.5
var b = 7 / 2;      // int: 3 — ¡división entera, fracción perdida!

Console.WriteLine(a);
Console.WriteLine(b);

var copia fielmente lo que produjo la expresión — incluidas las sorpresas de la división entera (historia completa: por qué 7 / 2 es 3).

Cuándo brilla var

Usa var cuando el tipo ya es obvio en la misma línea — entonces es pura reducción de ruido:

var nombres = new List<string>();    // obviamente List<string>
var perro   = new Perro("Rex", 3);    // obviamente Perro
var total   = precio * cantidad;      // bien cuando los tipos son simples

El caso de contenedores genéricos es donde más se siente — compara:

Dictionary<string, List<int>> notas = new Dictionary<string, List<int>>();  // escrito dos veces
var notas2 = new Dictionary<string, List<int>>();                          // escrito una vez
var notas = new Dictionary>();
notas["Ada"] = new List { 90, 85 };

Console.WriteLine($"Ada tiene {notas["Ada"].Count} notas");

Cuándo gana el tipo explícito

Escribe el tipo cuando es información que el lector no puede ver de otra forma:

var etiqueta = "cuenta: ";
int n = 5;
Console.WriteLine(etiqueta + n);   // bien: string + int concatena

var mal = n = etiqueta;            // tontería a propósito: string dentro de un int

Reglas que var debe cumplir

Convenciones de equipo, comprimidas

SituaciónUsaPor qué
new en la misma líneavarEl tipo ya está escrito a la derecha
Declaraciones numéricasexplícitoint vs double es información que sostiene la lógica
Resultados de métodosexplícito (o un buen nombre)El lector no debería tener que buscarlo
LINQ / genéricos complejosvarEl nombre completo del tipo sería más largo que la lógica

Casi todas las guías de estilo (incluida la de Microsoft) aterrizan en: usa var cuando el lado derecho hace obvio el tipo; si no, escríbelo. Cuando dos veteranos discuten, casi siempre discuten sobre qué cuenta como "obvio".