CSharp
Tutorial CSharp: Funciones
Aprende a crear funciones en C# con parámetros y retorno. Domina la sintaxis básica y buenas prácticas para código modular y reutilizable.
Aprende CSharp y certifícateSintaxis básica de una función
En C#, las funciones (también llamadas métodos) son bloques de código que realizan una tarea específica y pueden ser reutilizados en diferentes partes de un programa. Las funciones nos permiten organizar nuestro código de manera más eficiente, evitando la repetición y mejorando la legibilidad.
La sintaxis básica para definir una función en C# sigue un patrón claro y estructurado:
tipoDeRetorno NombreDeLaFuncion()
{
// Cuerpo de la función
// Código que se ejecutará cuando la función sea llamada
return valorDeRetorno; // Opcional, dependiendo del tipo de retorno
}
Vamos a analizar cada parte de esta estructura:
Modificador de acceso: Determina la visibilidad de la función. Aunque no es obligatorio, es común especificarlo. Los más comunes son:
public
: Accesible desde cualquier parte del programaprivate
: Solo accesible dentro de la misma claseprotected
: Accesible dentro de la clase y sus derivadasinternal
: Accesible dentro del mismo ensambladoTipo de retorno: Indica qué tipo de dato devolverá la función. Puede ser cualquier tipo válido en C# (int, string, bool, etc.) o
void
si la función no devuelve ningún valor.Nombre de la función: Debe ser un identificador válido en C#. Por convención, se utiliza PascalCase (primera letra de cada palabra en mayúscula).
Paréntesis (): Pueden contener parámetros (que veremos en la siguiente sección) o estar vacíos.
Cuerpo de la función: Delimitado por llaves
{}
, contiene el código que se ejecutará cuando la función sea llamada.Instrucción return: Si la función tiene un tipo de retorno distinto de
void
, debe incluir al menos una instrucciónreturn
que devuelva un valor del tipo especificado.
Veamos algunos ejemplos básicos:
Ejemplo 1: Una función simple que no recibe parámetros y no devuelve ningún valor:
public void MostrarMensaje()
{
Console.WriteLine("¡Hola desde mi primera función!");
}
Para llamar o invocar esta función, simplemente escribimos su nombre seguido de paréntesis:
MostrarMensaje(); // Imprime: ¡Hola desde mi primera función!
Ejemplo 2: Una función que devuelve un valor:
public int ObtenerNumeroAleatorio()
{
Random random = new Random();
int numero = random.Next(1, 101); // Genera un número entre 1 y 100
return numero;
}
Para usar esta función y capturar su valor de retorno:
int miNumero = ObtenerNumeroAleatorio();
Console.WriteLine($"El número aleatorio es: {miNumero}");
Ejemplo 3: Una función con modificador de acceso privado:
private bool EsFinDeSemana()
{
DayOfWeek diaDeLaSemana = DateTime.Now.DayOfWeek;
return diaDeLaSemana == DayOfWeek.Saturday || diaDeLaSemana == DayOfWeek.Sunday;
}
Esta función solo puede ser llamada desde dentro de la misma clase donde está definida.
Ubicación de las funciones en C#
En C#, las funciones siempre deben estar definidas dentro de una clase. No pueden existir de forma independiente como en otros lenguajes. Un ejemplo completo sería:
using System;
class Programa
{
// Método principal (punto de entrada)
static void Main()
{
SaludarUsuario();
bool esFinde = EsFinDeSemana();
Console.WriteLine($"¿Es fin de semana? {esFinde}");
}
// Función sin valor de retorno
static void SaludarUsuario()
{
Console.WriteLine("¡Bienvenido a mi programa!");
}
// Función con valor de retorno
static bool EsFinDeSemana()
{
DayOfWeek dia = DateTime.Now.DayOfWeek;
return dia == DayOfWeek.Saturday || dia == DayOfWeek.Sunday;
}
}
Observa que en este ejemplo hemos añadido el modificador static
a nuestras funciones. Esto es necesario para poder llamarlas desde el método Main
(que también es static
). El modificador static
indica que la función pertenece a la clase en sí, no a una instancia específica de la clase.
Buenas prácticas al definir funciones
- Usa nombres descriptivos que indiquen claramente lo que hace la función.
- Sigue la convención de PascalCase para los nombres de funciones.
- Cada función debe realizar una única tarea bien definida.
- Mantén las funciones cortas y concisas. Si una función es muy larga, considera dividirla en funciones más pequeñas.
- Documenta tus funciones con comentarios cuando sea necesario, especialmente si su propósito no es obvio.
/// <summary>
/// Calcula el área de un círculo dado su radio.
/// </summary>
/// <param name="radio">El radio del círculo en unidades.</param>
/// <returns>El área del círculo en unidades cuadradas.</returns>
public double CalcularAreaCirculo(double radio)
{
return Math.PI * radio * radio;
}
Con estos fundamentos, ya estás listo para crear y utilizar funciones básicas en C#. En las siguientes secciones, aprenderemos cómo trabajar con parámetros y valores de retorno de manera más avanzada.
Parámetros en funciones
Los parámetros son una parte fundamental de las funciones en C# que nos permiten enviar datos a una función para que trabaje con ellos. Gracias a los parámetros, nuestras funciones se vuelven más flexibles y reutilizables, ya que pueden operar con diferentes valores cada vez que las llamamos.
La sintaxis para definir parámetros es sencilla: se colocan dentro de los paréntesis de la declaración de la función, especificando el tipo de dato y un nombre para cada parámetro:
tipoDeRetorno NombreFuncion(tipoDato1 nombreParametro1, tipoDato2 nombreParametro2)
{
// Código que utiliza los parámetros
}
Parámetros simples
Veamos un ejemplo básico de una función con un parámetro:
static void Saludar(string nombre)
{
Console.WriteLine($"¡Hola, {nombre}!");
}
Para llamar a esta función, debemos proporcionar un argumento que coincida con el tipo de parámetro esperado:
Saludar("Ana"); // Imprime: ¡Hola, Ana!
Saludar("Carlos"); // Imprime: ¡Hola, Carlos!
Múltiples parámetros
Las funciones pueden recibir varios parámetros, separados por comas:
static void MostrarInformacion(string nombre, int edad)
{
Console.WriteLine($"{nombre} tiene {edad} años.");
}
Al llamar a la función, debemos proporcionar todos los argumentos en el mismo orden:
MostrarInformacion("Laura", 28); // Imprime: Laura tiene 28 años.
Parámetros con valores predeterminados
C# permite definir valores predeterminados para los parámetros. Estos valores se utilizarán cuando no se proporcione un argumento para ese parámetro:
static void ConfigurarUsuario(string nombre, bool esAdmin = false)
{
if (esAdmin)
Console.WriteLine($"{nombre} tiene permisos de administrador.");
else
Console.WriteLine($"{nombre} tiene permisos estándar.");
}
Esta función puede llamarse de dos maneras:
ConfigurarUsuario("Miguel"); // Usa el valor predeterminado false
// Imprime: Miguel tiene permisos estándar.
ConfigurarUsuario("Elena", true); // Sobrescribe el valor predeterminado
// Imprime: Elena tiene permisos de administrador.
Parámetros nombrados
Los parámetros nombrados nos permiten especificar a qué parámetro corresponde cada argumento, independientemente del orden:
static void CalcularEnvio(string destino, double peso, bool esUrgente = false)
{
double costo = peso * 2.5;
if (esUrgente) costo *= 1.5;
Console.WriteLine($"Envío a {destino} - Peso: {peso}kg - Costo: ${costo}");
}
Podemos llamar a esta función de varias formas:
// Forma tradicional
CalcularEnvio("Madrid", 3.5, true);
// Usando parámetros nombrados
CalcularEnvio(destino: "Barcelona", peso: 2.0, esUrgente: false);
// Cambiando el orden con parámetros nombrados
CalcularEnvio(esUrgente: true, peso: 1.5, destino: "Valencia");
// Combinando parámetros posicionales y nombrados
CalcularEnvio("Sevilla", peso: 4.2);
Los parámetros nombrados son especialmente útiles cuando una función tiene muchos parámetros o varios parámetros opcionales.
Parámetros de salida (out)
Los parámetros marcados con la palabra clave out
permiten que una función devuelva múltiples valores:
static void DividirConResto(int dividendo, int divisor, out int cociente, out int resto)
{
cociente = dividendo / divisor;
resto = dividendo % divisor;
}
Para usar esta función:
int resultado, residuo;
DividirConResto(17, 5, out resultado, out residuo);
Console.WriteLine($"17 ÷ 5 = {resultado} con resto {residuo}");
// Imprime: 17 ÷ 5 = 3 con resto 2
También podemos declarar las variables directamente en la llamada:
DividirConResto(17, 5, out int resultado, out int residuo);
Parámetros de referencia (ref)
La palabra clave ref
indica que un parámetro se pasa por referencia, lo que permite modificar el valor original:
static void Duplicar(ref int numero)
{
numero *= 2;
}
Para usar esta función:
int valor = 5;
Console.WriteLine($"Valor original: {valor}"); // Imprime: Valor original: 5
Duplicar(ref valor);
Console.WriteLine($"Valor duplicado: {valor}"); // Imprime: Valor duplicado: 10
La diferencia principal entre ref
y out
es que con ref
la variable debe estar inicializada antes de pasarla a la función, mientras que con out
no es necesario.
Número variable de parámetros (params)
La palabra clave params
permite que una función acepte un número variable de argumentos del mismo tipo:
static double Promedio(params int[] numeros)
{
int suma = 0;
foreach (int num in numeros)
{
suma += num;
}
return (double)suma / numeros.Length;
}
Esta función puede llamarse con cualquier cantidad de argumentos:
double media1 = Promedio(5, 10, 15);
Console.WriteLine($"Promedio 1: {media1}"); // Imprime: Promedio 1: 10
double media2 = Promedio(2, 4, 6, 8, 10);
Console.WriteLine($"Promedio 2: {media2}"); // Imprime: Promedio 2: 6
También podemos pasar un array directamente:
int[] valores = { 1, 2, 3, 4, 5 };
double media3 = Promedio(valores);
Buenas prácticas con parámetros
Limita el número de parámetros: Una función con demasiados parámetros puede ser difícil de usar. Si necesitas muchos parámetros, considera usar una clase o estructura.
Usa nombres descriptivos: Los nombres de los parámetros deben indicar claramente qué representan.
Valida los parámetros: Verifica que los valores recibidos sean válidos antes de usarlos.
static double CalcularAreaRectangulo(double ancho, double alto)
{
if (ancho <= 0 || alto <= 0)
{
throw new ArgumentException("Las dimensiones deben ser positivas");
}
return ancho * alto;
}
- Considera la inmutabilidad: Evita modificar los parámetros de entrada a menos que sea necesario y esté claramente indicado (como con
ref
oout
).
Los parámetros son una herramienta esencial que hace que nuestras funciones sean verdaderamente útiles y versátiles. Dominar los diferentes tipos de parámetros te permitirá crear código más flexible y reutilizable en tus aplicaciones C#.
Retorno de función
El retorno de una función es el mecanismo mediante el cual una función puede devolver un valor al código que la llamó. Esta característica es fundamental en la programación ya que permite que las funciones no solo realicen acciones, sino que también produzcan resultados que pueden ser utilizados posteriormente en el programa.
En C#, el tipo de retorno de una función se especifica antes del nombre de la función en su declaración. Este tipo puede ser cualquier tipo de dato válido en C#, incluyendo tipos primitivos (como int
, double
, bool
), tipos de referencia (como string
, array
), o incluso tipos definidos por el usuario.
Funciones con retorno de valor
Para crear una función que devuelva un valor, debemos:
- Especificar el tipo de dato que devolverá la función
- Utilizar la palabra clave
return
seguida del valor a devolver
static int Sumar(int a, int b)
{
int resultado = a + b;
return resultado;
}
También podemos simplificar esta función:
static int Sumar(int a, int b)
{
return a + b;
}
Para utilizar el valor devuelto por una función, simplemente asignamos la llamada a una variable del tipo adecuado:
int suma = Sumar(5, 3);
Console.WriteLine($"La suma es: {suma}"); // Imprime: La suma es: 8
También podemos usar el valor directamente en una expresión:
Console.WriteLine($"El doble de la suma es: {Sumar(5, 3) * 2}"); // Imprime: El doble de la suma es: 16
Funciones sin valor de retorno (void)
Cuando una función no necesita devolver ningún valor, utilizamos el tipo especial void
:
static void MostrarMensaje(string mensaje)
{
Console.WriteLine(mensaje);
// No hay instrucción return con valor
}
Las funciones void
pueden terminar su ejecución de dos formas:
- Cuando se llega al final del cuerpo de la función
- Mediante una instrucción
return
sin valor
static void VerificarEdad(int edad)
{
if (edad < 0)
{
Console.WriteLine("La edad no puede ser negativa");
return; // Termina la ejecución de la función
}
Console.WriteLine($"La edad es: {edad} años");
}
Retorno de diferentes tipos de datos
Las funciones pueden devolver cualquier tipo de dato en C#:
Tipos numéricos:
static double CalcularPromedio(int[] numeros)
{
int suma = 0;
foreach (int num in numeros)
{
suma += num;
}
return (double)suma / numeros.Length;
}
Tipos booleanos:
static bool EsNumeroValido(int numero)
{
return numero >= 0 && numero <= 100;
}
Cadenas de texto:
static string ObtenerSaludo(string nombre)
{
return $"¡Hola, {nombre}! Bienvenido/a.";
}
Arrays:
static int[] GenerarSecuencia(int inicio, int fin)
{
int longitud = fin - inicio + 1;
int[] secuencia = new int[longitud];
for (int i = 0; i < longitud; i++)
{
secuencia[i] = inicio + i;
}
return secuencia;
}
Múltiples instrucciones return
Una función puede tener múltiples instrucciones return
, pero solo se ejecutará una de ellas:
static string ClasificarNumero(int numero)
{
if (numero < 0)
{
return "Negativo";
}
else if (numero == 0)
{
return "Cero";
}
else
{
return "Positivo";
}
}
Retorno implícito en expresiones lambda
En C# también podemos crear funciones más concisas utilizando expresiones lambda con retorno implícito:
// Función tradicional
static int Cuadrado(int n)
{
return n * n;
}
// Equivalente con expresión lambda
static int CuadradoLambda(int n) => n * n;
Uso práctico de funciones con retorno
Veamos un ejemplo práctico que combina varias funciones con diferentes tipos de retorno:
static void Main()
{
// Solicitar datos al usuario
Console.Write("Ingrese la temperatura en Celsius: ");
double celsius = Convert.ToDouble(Console.ReadLine());
// Convertir temperatura
double fahrenheit = CelsiusAFahrenheit(celsius);
// Mostrar resultado
Console.WriteLine($"{celsius}°C equivale a {fahrenheit}°F");
// Clasificar la temperatura
string sensacion = ClasificarTemperatura(celsius);
Console.WriteLine($"Sensación térmica: {sensacion}");
}
static double CelsiusAFahrenheit(double celsius)
{
return (celsius * 9 / 5) + 32;
}
static string ClasificarTemperatura(double celsius)
{
if (celsius < 0)
{
return "Muy frío";
}
else if (celsius < 10)
{
return "Frío";
}
else if (celsius < 25)
{
return "Templado";
}
else if (celsius < 30)
{
return "Cálido";
}
else
{
return "Muy caliente";
}
}
Buenas prácticas para el retorno de funciones
Coherencia en el tipo de retorno: Asegúrate de que el tipo de retorno sea coherente con lo que la función debe devolver.
Nombres descriptivos: El nombre de la función debe indicar claramente qué valor devuelve.
// Buen nombre para una función que devuelve un booleano
static bool EsNumeroPrimo(int numero)
// Buen nombre para una función que devuelve un valor
static double CalcularImpuesto(double precio)
Evita efectos secundarios: Una función que devuelve un valor debería centrarse en calcular ese valor, no en realizar otras acciones como modificar variables globales o mostrar mensajes.
Validación de datos: Considera qué debe devolver la función en casos excepcionales.
static int DividirSeguro(int dividendo, int divisor)
{
if (divisor == 0)
{
// Podríamos lanzar una excepción, pero para simplificar:
return 0; // O algún otro valor que indique error
}
return dividendo / divisor;
}
- Consistencia en los valores de retorno: Si una función puede devolver un error, mantén un enfoque consistente (usar excepciones, códigos de error, etc.).
El uso efectivo del retorno de funciones te permitirá crear código más modular, reutilizable y fácil de mantener. Las funciones bien diseñadas que devuelven valores apropiados son la base de un código limpio y estructurado en C#.
Otros ejercicios de programación de CSharp
Evalúa tus conocimientos de esta lección Funciones con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
CRUD en C# de modelo Customer sobre una lista
Arrays y listas
Objetos
Excepciones
Eventos
Lambdas
Diccionarios en C#
Variables y constantes
Tipos de datos
Herencia
Operadores
Uso de consultas LINQ
Clases y encapsulación
Uso de consultas LINQ
Excepciones
Control de flujo
Eventos
Diccionarios
Tipos de datos
Conjuntos, colas y pilas
Lambdas
Conjuntos, colas y pilas
Uso de async y await
Tareas
Constructores y destructores
Operadores
Arrays y listas
Polimorfismo
Polimorfismo
Variables y constantes
Proyecto colecciones y LINQ en C#
Clases y encapsulación
Creación de proyecto C#
Uso de async y await
Funciones
Delegados
Delegados
Constructores y destructores
Objetos
Control de flujo
Funciones
Tareas
Proyecto sintaxis en C#
Herencia C Sharp
OOP en C Sharp
Diccionarios
Introducción a C#
Todas las lecciones de CSharp
Accede a todas las lecciones de CSharp y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A C#
Introducción Y Entorno
Creación De Proyecto C#
Introducción Y Entorno
Variables Y Constantes
Sintaxis
Tipos De Datos
Sintaxis
Operadores
Sintaxis
Control De Flujo
Sintaxis
Funciones
Sintaxis
Estructuras De Control Iterativo
Sintaxis
Interpolación De Strings
Sintaxis
Estructuras De Control Condicional
Sintaxis
Manejo De Valores Nulos
Sintaxis
Clases Y Encapsulación
Programación Orientada A Objetos
Objetos
Programación Orientada A Objetos
Constructores Y Destructores
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Genéricos
Programación Orientada A Objetos
Métodos Virtuales Y Sobrecarga
Programación Orientada A Objetos
Clases Abstractas
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Propiedades Y Encapsulación
Programación Orientada A Objetos
Métodos De Extensión
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Clases Parciales
Programación Orientada A Objetos
Miembros Estáticos
Programación Orientada A Objetos
Tuplas Y Tipos Anónimos
Programación Orientada A Objetos
Arrays Y Listas
Colecciones Y Linq
Diccionarios
Colecciones Y Linq
Conjuntos, Colas Y Pilas
Colecciones Y Linq
Uso De Consultas Linq
Colecciones Y Linq
Linq Avanzado
Colecciones Y Linq
Colas Y Pilas
Colecciones Y Linq
Conjuntos
Colecciones Y Linq
Linq Básico
Colecciones Y Linq
Delegados Funcionales
Programación Funcional
Records
Programación Funcional
Expresiones Lambda
Programación Funcional
Linq Funcional
Programación Funcional
Fundamentos De La Programación Funcional
Programación Funcional
Pattern Matching
Programación Funcional
Testing Unitario Con Xunit
Testing
Excepciones
Excepciones
Delegados
Programación Asíncrona
Eventos
Programación Asíncrona
Lambdas
Programación Asíncrona
Uso De Async Y Await
Programación Asíncrona
Tareas
Programación Asíncrona
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la sintaxis básica para definir funciones en C#.
- Aprender a utilizar diferentes tipos de parámetros, incluyendo valores predeterminados, nombrados, out, ref y params.
- Entender cómo funcionan los valores de retorno en funciones y su importancia.
- Conocer las buenas prácticas para definir funciones claras, concisas y reutilizables.
- Saber cómo organizar funciones dentro de clases y el uso del modificador static.