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 te permiten añadir 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 tu código sea más legible e intuitivo.
Para crear un método de extensión, define 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 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 usa ampliamente en LINQ, donde métodos como Where() y Select() son métodos de extensión de 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ácilConstruyamos un conjunto de métodos de extensión útiles para enteros que añadan la funcionalidad práctica que esperarías que estuviera integrada. Crearás una clase estática que contenga métodos de extensión que puedan invocarse 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, yfalseen caso contrarioSquare()- devuelve el número multiplicado por sí mismoIsInRange(int min, int max)- devuelvetruesi el número está entre min y max (inclusive), yfalseen 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, y después imprime los resultados.
Recibirás tres entradas:
- Un número que probar (entero)
- Valor mínimo para la comprobación del rango (entero)
- Valor máximo para la comprobación del rango (entero)
Imprime la salida con 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]? TrueObserva lo natural que resulta escribir number.IsEven() y number.Square(): ¡los métodos de extensión parecen haber formado parte del tipo entero desde siempre!
Prué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: Usa los métodos de extensión en 'number' e imprime los resultados
// Llama a number.IsEven(), number.Square() y number.IsInRange(min, max)
// Imprime 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 estudiantesPractica por tu cuenta: Compilador de C# online