C#: Métodos con parámetros opcionales

En ciertos casos, podemos encontrarnos en la situación de tener un método con cierta cantidad de parámetros (pocos o muchos), de los cuales algunos los usamos en ciertos casos, y otros no.

Por ejemplo, si en mi base de datos hay una tabla de usuarios, muy probablemente tendré consultas diferentes a esa tabla: Para la administración de usuarios requiero traerme todos los registros; para seleccionar un usuario para cierta acción, probablemente necesite solo a los usuarios activos; para obtener la información de un solo usuario debo buscarlo por su clave; para iniciar sesión debo consultar por nombre de usuario y contraseña. Todas éstas son consultas a una misma tabla, que me traerán toda su información, pero dependerán de distintos parámetros.

// Método global para consulta de Usuarios
public DataTable Consulta(int id, string nombre, string password, bool? activo){
  DataTable table = new DataTable();
  using (SqlDataAdapter adapter = new SqlDataAdapter(
    "Consulta_Usuarios", "[connectionString]") {
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
    // Por cada parámetro, si no está vacío, lo agrego a la consulta SQL.
    if (id > 0)
      adapter.SelectCommand.Parameters.AddWithValue("@id", id);
    if (!string.IsNullOrEmpty(nombre))
      adapter.SelectCommand.Parameters.AddWithValue("@nombre", nombre);
    if (!string.IsNullOrEmpty(password))
      adapter.SelectCommand.Parameters.AddWithValue("@password", password);
    if (activo.HasValue)
      adapter.SelectCommand.Parameters.AddWithValue("@activo", activo.Value);

    adapter.Fill(table);
  }
  return table;
}

En la programación Orientada a Objetos existe una característica llamada «sobrecarga de métodos», la cual nos permite crear distintos métodos con un mismo nombre pero distintos parámetros. Esto nos permite ejecutar un método con datos diferentes para realizar distintas operaciones.

public DataTable ConsultarTodos(){
  return Consulta(0, "", "", null);
}
public DataTable ConsultarActivos(){
  return Consulta(0, "", "", true);
}
public DataTable ConsultarPorID(int id){
  return Consulta(id, "", "", null);
}
public DataTable IniciarSesion(string nombre, string password){
  return Consulta(0, nombre, password, null);
}

Algo complejo, pero nos facilita la creación de métodos más específicos para las operaciones que se requieran.

Como complemento a esto, C# incluye una característica (probablemente basada en una similar de VB), que nos permite definir los parámetros como opcionales, es decir, que al invocar un método, no sea obligatorio enviarle ciertos parámetros.

public DataTable Consulta(
  int id = 0, string nombre = "", string password = "", bool? activo = null){
  DataTable table = new DataTable();
  using (SqlDataAdapter adapter = new SqlDataAdapter(
    "Consulta_Usuarios", "[connectionString]") {
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
    if (id > 0)
      adapter.SelectCommand.Parameters.AddWithValue("@id", id);
    if (!string.IsNullOrEmpty(nombre))
      adapter.SelectCommand.Parameters.AddWithValue("@nombre", nombre);
    if (!string.IsNullOrEmpty(password))
      adapter.SelectCommand.Parameters.AddWithValue("@password", password);
    if (activo.HasValue)
      adapter.SelectCommand.Parameters.AddWithValue("@activo", activo.Value);
    adapter.Fill(table);
  }
  return table;
}

Si le asignamos un valor a un parámetro del método, C# lo considerará como opcional, y en caso de no enviar un valor al invocar el método, ése valor será el que éste reciba.

Una característica más de C# es la de permitir que los parámetros de un método (de cualquier tipo) puedan ser llamados en cualquier orden, siempre y cuando se indique cuál parámetro se está enviando.

// La sintáxis normal de este método es string.Format(format, arg0, arg1, arg2)
// En este ejemplo se muestra cómo se puede cambiar el orden de los parámetros
// y el resultado seguirá siendo correcto: http://deployando.net
string.Format(arg1: "deployando", arg2: "net", format: "{0}://{1}.{2}", arg0: "http");

Esto también es útil para el uso de parámetros opcionales, ya que así es como invocamos a un método enviando únicamente ciertos parámetros.

var usuariosTodos = Consulta();
var usuariosActivos = Consulta(activo: true);
var usuario = Consulta(id: 4);
var sesion = Consulta(nombre: "usuario", password: "usu123.321");

Los parámetros no enviados utilizarán su valor predeterminado, especificado en la declaración del método, y el cuerpo del método los manejará como esté definido (como en el caso de nuestro método, no agregando los parámetros correspondientes a la sentencia SQL).

Dentro de la definición de parámetros se pueden incluir requeridos y opcionales a la vez. La única condición es que todos los parámetros opcionales deben estar después de los requeridos, esto para permitir invocar el método únicamente con los parámetros requeridos en el orden que están definidos.

Anuncio publicitario

4 comentarios sobre “C#: Métodos con parámetros opcionales

  1. Hola,

    Gracias por el post, pero tengo dos humildes sugerencias …

    1- Cuando hablas de parámetros opcionales, deberías de mencionar el nombre técnico verdadero de esos tipos de datos; es decir, tipos nullables en C#:

    http://msdn.microsoft.com/es-es/library/1t3y8s4s.aspx

    2- Cada condición como esta:

    if (!string.IsNullOrEmpty(nombre))
    adapter.SelectCommand.Parameters.AddWithValue(«@nombre», nombre);

    La podrias optimizar en terminos de rendimiento y lineas de código con el operador ?:

    http://msdn.microsoft.com/es-es/library/ty67wk28(v=vs.80).aspx

    1. Gracias por tu comentario 🙂
      Los tipos nullable son algo distinto. Estos son para definir una variable que puede o puede no tener valor (muy útiles en los tipos de datos básicos (int, string, byte) y otros como DateTime, que no admiten null. De eso hablé en otro artículo hace tiempo https://deployando.net/2010/07/28/cs-nulos/.
      En este artículo hablo de cómo agregar parámetros que pueden o no ser invocados al llamar al método.

Responder a heb Cancelar la respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s