Os métodos de extensão não fornecem algo que não possa ser feito de outras maneiras. Eles são açúcar sintático para tornar o desenvolvimento mais agradável, sem fornecer um benefício técnico real.
Os métodos de extensão são relativamente novos. Padrões e convenções geralmente são decididos pela opinião popular (além de alguma experiência de longo prazo sobre o que acaba sendo uma má idéia), e não acho que estamos no ponto em que podemos traçar uma linha definitiva com a qual todos concordam.
No entanto, posso ver vários argumentos, com base nas coisas que ouvi de colegas de trabalho.
1. Eles geralmente estão substituindo métodos estáticos.
Os métodos de extensão são mais comumente baseados em coisas que seriam métodos estáticos, não métodos de classe. Eles se parecem com métodos de classe, mas na verdade não são.
Métodos de extensão simplesmente não devem ser considerados uma alternativa para métodos de classe; mas como uma maneira de fornecer aos métodos estáticos sintaticamente alternados uma aparência e um "método de classe".
2. Quando o método pretendido for específico para um projeto consumidor, mas não a biblioteca de origem.
Só porque você desenvolve a biblioteca e o consumidor não significa que você está disposto a colocar a lógica onde quer que ela se encaixe.
Por exemplo:
- Você tem uma
PersonDto
turma vinda do seu DataLayer
projeto.
- Seu
WebUI
projeto deseja converter um PersonDto
para um PersonViewModel
.
Você não pode (e não gostaria de) adicionar esse método de conversão ao seu DataLayer
projeto. Como esse método está no escopo do WebUI
projeto, ele deve residir dentro desse projeto.
Um método de extensão permite que você tenha esse método acessível globalmente dentro do seu projeto (e possíveis consumidores do seu projeto), sem exigir que a DataLayer
biblioteca o implemente.
3. Se você acha que as classes de dados devem conter apenas dados.
Por exemplo, sua Person
classe contém as propriedades para uma pessoa. Mas você deseja ter alguns métodos que formatam alguns dos dados:
public class Person
{
//The properties...
public SecurityQuestionAnswers GetSecurityAnswers()
{
return new SecurityQuestionAnswers()
{
MothersMaidenName = this.Mother.MaidenName,
FirstPetsName = this.Pets.OrderbyDescending(x => x.Date).FirstOrDefault()?.Name
};
}
}
Eu já vi muitos colegas de trabalho que odeiam a idéia de misturar dados e lógica em uma classe. Não concordo com coisas simples, como formatação de dados, mas admito que, no exemplo acima, parece sujo Person
ter que depender SecurityQuestionAnswers
.
Colocar esse método em um método de extensão evita o manuseio da classe de dados pura.
Observe que esse argumento é de estilo. Isso é semelhante às classes parciais. Há pouco ou nenhum benefício técnico em fazê-lo, mas ele permite que você separe o código em vários arquivos se você o considerar mais limpo (por exemplo, se muitas pessoas usarem a classe, mas não se importarem com seus métodos personalizados adicionais).
4. Métodos auxiliares
Na maioria dos projetos, acabo tendo aulas auxiliares. Essas são classes estáticas que geralmente fornecem uma coleção de métodos para facilitar a formatação.
Por exemplo, uma empresa em que trabalhei tinha um formato de data e hora específico que eles queriam usar. Em vez de colar a string de formato em todo o lugar ou transformar a string de formato em uma variável global, optei pelo método de extensão DateTime:
public static string ToCompanyFormat(this DateTime dt)
{
return dt.ToString("...");
}
Isso é melhor do que um método auxiliar estático normal? Acho que sim. Ele limpa a sintaxe. Ao invés de
DateTimeHelper.ToCompanyFormat(myObj.CreatedOn);
Eu poderia fazer:
myObj.CreatedOn.ToCompanyFormat();
Isso é semelhante a uma versão fluente da mesma sintaxe. Gosto mais, mesmo que não exista nenhum benefício técnico em ter um sobre o outro.
Todos esses argumentos são subjetivos. Nenhum deles cobre um caso que nunca poderia ser coberto.
- Todo método de extensão pode ser facilmente reescrito para um método estático normal.
- O código pode ser separado em arquivos usando classes parciais, mesmo que não existam métodos de extensão.
Mas, novamente, podemos aceitar sua afirmação de que eles nunca são necessários ao extremo:
- Por que precisamos de métodos de classe, se podemos sempre criar métodos estáticos com um nome que indique claramente que é para uma classe específica?
A resposta a esta pergunta, e a sua, permanece a mesma:
- Sintaxe mais agradável
- Maior legibilidade e menos pedantry de código (o código chegará ao ponto em menos caracteres)
- O Intellisense fornece resultados contextualmente significativos (os métodos de extensão são mostrados apenas no tipo correto. As classes estáticas são utilizáveis em qualquer lugar).
Uma menção extra específica:
- Os métodos de extensão permitem um método de encadeamento de códigos; que se tornou mais popular ultimamente, em oposição à sintaxe de quebra de método de baunilha. Preferências sintáticas semelhantes podem ser vistas na sintaxe do método do LINQ.
- Embora o encadeamento de métodos também possa ser feito usando métodos de classe; lembre-se de que isso não se aplica aos métodos estáticos. Os métodos de extensão são mais comumente baseados em coisas que seriam métodos estáticos, não métodos de classe.