Métodos de Extensão
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy — lição 39 de 70.
Métodos de extensão permitem que você adicione novos métodos a tipos existentes sem modificar seu código-fonte ou criar classes derivadas. Eles aparecem como se fossem métodos nativos do tipo, tornando seu código mais legível e intuitivo.
Para criar um método de extensão, defina um método estático em uma classe estática, com o primeiro parâmetro precedido pela palavra-chave this:
public static class StringExtensions
{
public static int WordCount(this string str)
{
return str.Split(' ').Length;
}
}Agora você pode chamar este método diretamente em qualquer string:
string sentence = "Hello World Today";
int count = sentence.WordCount(); // 3O parâmetro this string str informa ao compilador que este método estende o tipo string. Quando você chama sentence.WordCount(), o compilador o traduz para StringExtensions.WordCount(sentence) nos bastidores.
Métodos de extensão também podem aceitar parâmetros adicionais:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
// Uso
bool result = "Hello".IsLongerThan(3); // trueEsta técnica é usada extensivamente no LINQ, onde métodos como Where() e Select() são métodos de extensão em IEnumerable. Métodos de extensão são poderosos para adicionar funções utilitárias a tipos que você não controla, mantendo seu código limpo e expressivo.
Desafio
FácilVamos construir um conjunto de métodos de extensão úteis para inteiros que adicionam funcionalidades convenientes que você esperaria ter de forma nativa. Você criará uma classe estática contendo métodos de extensão que podem ser chamados diretamente em qualquer inteiro, tornando seu código mais expressivo e legível.
Você organizará seu código em dois arquivos:
IntExtensions.cs: Crie uma classe estática chamadaIntExtensionsno namespaceUtilities. Esta classe conterá métodos de extensão que aprimoram o tipoint:IsEven()- retornatruese o número for par,falsecaso contrárioSquare()- retorna o número multiplicado por si mesmoIsInRange(int min, int max)- retornatruese o número estiver entre min e max (inclusive),falsecaso contrário
thispara especificar qual tipo você está estendendo.Program.cs: No seu arquivo principal, leia um inteiro da entrada e demonstre todos os três métodos de extensão. Chame cada método diretamente no inteiro como se fosse um método nativo e, em seguida, imprima os resultados.
Você receberá três entradas:
- Um número para testar (inteiro)
- Valor mínimo para a verificação de intervalo (inteiro)
- Valor máximo para a verificação de intervalo (inteiro)
Imprima a saída neste formato:
Is {number} even? {True/False}
Square of {number}: {result}
Is {number} in range [{min}-{max}]? {True/False}Por exemplo, se as entradas forem 7, 5 e 10, a saída deve ser:
Is 7 even? False
Square of 7: 49
Is 7 in range [5-10]? TrueObserve como você pode escrever naturalmente number.IsEven() e number.Square() - os métodos de extensão parecem que sempre fizeram parte do tipo inteiro!
Folha de consulta
Métodos de extensão permitem que você adicione novos métodos a tipos existentes sem modificar seu código-fonte. Eles devem ser definidos como métodos estáticos em uma classe estática, com o primeiro parâmetro precedido pela palavra-chave this.
Sintaxe básica de um método de extensão:
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(); // 3A palavra-chave this antes do primeiro parâmetro indica qual tipo está sendo estendido. O compilador traduz sentence.WordCount() para StringExtensions.WordCount(sentence).
Métodos de extensão com parâmetros adicionais:
public static bool IsLongerThan(this string str, int length)
{
return str.Length > length;
}
bool result = "Hello".IsLongerThan(3); // trueExperimente você mesmo
using System;
using Utilities;
class Program
{
public static void Main(string[] args)
{
// Ler entradas
int number = Convert.ToInt32(Console.ReadLine());
int min = Convert.ToInt32(Console.ReadLine());
int max = Convert.ToInt32(Console.ReadLine());
// TODO: Use os métodos de extensão em 'number' e imprima os resultados
// Chame number.IsEven(), number.Square(), e number.IsInRange(min, max)
// Imprima no formato:
// Is {number} even? {True/False}
// Square of {number}: {result}
// Is {number} in range [{min}-{max}]? {True/False}
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de Métodos