1. Valores por defecto para parámetros
Imagínate una cafetería: si no dices si quieres azúcar en el café, el barista por defecto te pone una cucharada. Pero a veces quieres... ¡dos! O nada de azúcar (¡heroísmo!). Lo mismo pasa con los métodos: a veces mola que algunos parámetros tengan valores estándar si no los especificas.
Y los argumentos nombrados son como poder decir en tu pedido de café: «Y la leche me la pones de soja, no normal», sin importar el orden habitual de los ingredientes.
En C# ambos mecanismos hacen tu código más limpio, cómodo y te salvan de errores. Se usan un montón en proyectos reales: desde librerías de .NET hasta frameworks populares — por eso a los empleadores les mola ver que los dominas.
Sintaxis
El valor por defecto para un parámetro de función se pone directamente en la declaración del método usando el signo =. Si al llamar al método no pasas ese parámetro, se usa el valor por defecto que pusiste.
void PrintStudent(string name, int age = 18)
{
Console.WriteLine($"Estudiante: {name}, edad: {age}");
}
¿Cómo funciona?
- Si llamas PrintStudent("Alisa"); — se mostrará: Estudiante: Alisa, edad: 18.
- Si llamas PrintStudent("Sasha", 22); — se mostrará: Estudiante: Sasha, edad: 22.
¿Funciona para cualquier tipo?
Puedes poner valor por defecto para cualquier tipo de parámetro, pero hay matices:
- Para tipos de referencia (string, clases, etc.): puedes poner por defecto null o un literal concreto.
- Para tipos de valor (int, double, bool, etc.): pones el literal que quieras.
- Para enumeraciones (enum), structs: también puedes usar valores por defecto.
void AddStudent(string name, int course = 1, double averageScore = 5.0, string comment = null)
{
Console.WriteLine($"Añadido estudiante: {name}, curso: {course}, nota media: {averageScore}, comentario: {comment}");
}
Llamadas:
- AddStudent("Ivan");
- AddStudent("Maria", 2);
- AddStudent("Fiodor", 2, 4.7, "Con honores");
Orden de los parámetros con valores
Todos los parámetros opcionales (con valor por defecto) tienen que ir a la derecha (después de los obligatorios). Si intentas poner un parámetro con valor por defecto antes de uno obligatorio, el compilador te va a cerrar la puerta en la cara.
// ¡Error!
void Test(int a = 1, int b)
{
// ...
}
¿Por qué? Porque si no, el compilador no sabría a qué parámetro corresponde cada argumento cuando llamas al método.
2. Argumentos nombrados
Por defecto, cuando llamas a un método y pasas argumentos, el orden tiene que ser exactamente el mismo que el de los parámetros en la definición del método. Pero a veces la lista es larga, algunos parámetros tienen valores por defecto, y es fácil liarse.
Los argumentos nombrados te dejan indicar explícitamente a qué parámetro le pasas cada argumento, en cualquier orden.
AddStudent(name: "Elizaveta", averageScore: 4.2, comment: "Mejor estudiante del semestre");
- Aquí no ponemos el curso (course), así que será 1 (por defecto).
- No hace falta recordar en qué posición estaba el parámetro comment — solo pones su nombre.
Puedes incluso cambiar el orden de los parámetros:
AddStudent(averageScore: 3.7, name: "Georgiy");
¡Esto es súper cómodo y el código se entiende mucho mejor!
Uso con argumentos posicionales
Puedes mezclar argumentos nombrados y posicionales (sin nombre), pero todos los posicionales tienen que ir antes de los nombrados.
// Correcto
AddStudent("Sergey", averageScore: 4.9);
// Error
AddStudent(course: 2, "Filipp");
Después del primer argumento nombrado, todo lo demás tiene que ser solo nombrado. El compilador es muy estricto con este orden para que no te lleves sorpresas.
Comodidad en métodos con muchos parámetros
Esto se usa mucho cuando tienes métodos con un montón de opciones extra. Por ejemplo, si escribieras una función para añadir un usuario a alguna base de datos en la nube:
void RegisterUser(
string username,
string password,
string email = null,
bool admin = false,
bool sendWelcomeEmail = true,
string language = "ru"
)
Una llamada sin argumentos nombrados sería un infierno:
RegisterUser("cat", "qwerty", null, false, true, "ru");
Con argumentos nombrados todo es claro y seguro:
RegisterUser("cat", "qwerty", admin: true, sendWelcomeEmail: false, language: "en");
Consejo: usa argumentos nombrados para que el código se entienda incluso sin documentación.
3. Particularidades y errores comunes
Cuando empiezas a usar valores por defecto y argumentos nombrados, puedes meter la pata en varias cosas.
- Orden de los parámetros. Pon siempre los parámetros con valores por defecto después de los obligatorios. Si los mezclas, el compilador te va a dar error.
- Cambiar el valor por defecto en una librería. Si cambias el valor por defecto en una librería, los clientes antiguos no van a usar el nuevo automáticamente. El valor por defecto se compila en el código que llama. Así que piénsalo bien antes de cambiar valores por defecto en librerías públicas.
- Mezclar argumentos posicionales y nombrados. Si mezclas posicionales y nombrados, pero después de un nombrado pones otro posicional — no va a funcionar. Por ejemplo: Func(a: 1, 2) — dará error.
- Error de escritura en el nombre del parámetro. El compilador aquí es muy estricto: si te equivocas escribiendo (por ejemplo, pones naem: "Misha"), te dará un error tipo: "No existe ese parámetro, ¿qué estás haciendo?".
GO TO FULL VERSION