Métodos de extensión
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy — lección 39 de 70.
Los métodos de extensión le permiten agregar nuevos métodos a tipos existentes sin modificar su código fuente ni crear clases derivadas. Aparecen como si fueran métodos nativos del tipo, lo que hace que su código sea más legible e intuitivo.
Para crear un método de extensión, defina un método estático en una clase estática, con el primer parámetro precedido por la palabra clave this:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Ahora puedes llamar a este método directamente en cualquier cadena:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3El parámetro this string str le indica al compilador que este método extiende el tipo string. Cuando llamas a sentence.WordCount(), el compilador lo traduce a StringExtensions.WordCount(sentence) internamente.
Los métodos de extensión también pueden aceptar parámetros adicionales:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
// Uso
bool result = "Hello".IsLongerThan(3); // trueEsta técnica se utiliza ampliamente en LINQ, donde métodos como Where() y Select() son métodos de extensión en IEnumerable. Los métodos de extensión son potentes para añadir funciones de utilidad a tipos que no controlas, manteniendo tu código limpio y expresivo.
Desafío
FácilVamos a construir un conjunto de métodos de extensión útiles para enteros que añaden funcionalidades convenientes que esperarías tener integradas. Crearás una clase estática que contenga métodos de extensión que se pueden llamar directamente sobre cualquier entero, haciendo que tu código sea más expresivo y legible.
Organizarás tu código en dos archivos:
IntExtensions.cs: Crea una clase estática llamadaIntExtensionsen el espacio de nombresUtilities. Esta clase contendrá métodos de extensión que mejoran el tipoint:IsEven()- devuelvetruesi el número es par,falseen caso contrarioSquare()- devuelve el número multiplicado por sí mismoIsInRange(int min, int max)- devuelvetruesi el número está entre min y max (inclusive),falseen caso contrario
thispara especificar qué tipo estás extendiendo.Program.cs: En tu archivo principal, lee un entero de la entrada y demuestra los tres métodos de extensión. Llama a cada método directamente sobre el entero como si fuera un método integrado, luego imprime los resultados.
Recibirás tres entradas:
- Un número para probar (entero)
- Valor mínimo para la comprobación de rango (entero)
- Valor máximo para la comprobación de rango (entero)
Imprime la salida en este formato:
Is {number} even? {True/False}
Square of {number}: {result}
Is {number} in range [{min}-{max}]? {True/False}Por ejemplo, si las entradas son 7, 5 y 10, la salida debería ser:
Is 7 even? False
Square of 7: 49
Is 7 in range [5-10]? True¡Observa qué natural resulta escribir number.IsEven() y number.Square(); los métodos de extensión se sienten como si siempre hubieran formado parte del tipo entero!
Hoja de referencia
Los métodos de extensión le permiten agregar nuevos métodos a tipos existentes sin modificar su código fuente. Deben definirse como métodos estáticos en una clase estática, con el primer parámetro precedido por la palabra clave this.
Sintaxis básica de un método de extensión:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Uso:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3La palabra clave this antes del primer parámetro indica qué tipo se está extendiendo. El compilador traduce sentence.WordCount() a StringExtensions.WordCount(sentence).
Métodos de extensión con parámetros adicionales:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
bool result = "Hello".IsLongerThan(3); // truePruébalo tú mismo
using System;
using Utilities;
class Program
{
public static void Main(string[] args)
{
// Leer entradas
int number = Convert.ToInt32(Console.ReadLine());
int min = Convert.ToInt32(Console.ReadLine());
int max = Convert.ToInt32(Console.ReadLine());
// TODO: Usar los métodos de extensión en 'number' e imprimir los resultados
// Llamar a number.IsEven(), number.Square(), y number.IsInRange(min, max)
// Imprimir en el formato:
// Is {number} even? {True/False}
// Square of {number}: {result}
// Is {number} in range [{min}-{max}]? {True/False}
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantes