Pergunta

Um aspecto interessante dos métodos de extensão no .NET é o fato de que você pode aplicá -los às interfaces. Para mim, parece bom que eu possa definir a funcionalidade próxima à interface sem definir uma classe abstrata que se apega à montagem.

Sei que as classes abstratas não são obsoletas ou algo assim, mas como você se sente em utilizar esse efeito colateral em seu código?

Exemplo:

public static class IUserExtensions
{
    public static bool IsCurrentUser(this IUser user)
    {
        return (HttpContext.Current.User != null &&
                HttpContext.Current.User.Identity.Name == user.ID.ToString());
    }
}

public interface IUser {
    int ID { get; set; }
}
Foi útil?

Solução

Quais métodos de extensão permite que você faça é se concentrar em quais classes abstratas devem realmente estar fazendo. Há uma tentação de implementar o código "utilitário" em classes abstratas, pois será usado pelos implementadores, mesmo que não faça parte da árvore de herança lógica. Os métodos de extensão permitem anexar esses métodos de utilidade à interface sem atravessar suas classes base abstratas.

EDITAR

Especificamente, eu aplicaria essas diretrizes.

Herança

  • Use a herança se o comportamento faz parte do comportamento lógico da classe base
  • Não use a herança se o comportamento for transversal (aplica-se a coisas fora da hierarquia de objetos). Isso exigirá duplicação.

Classes de utilidade

  • Use classes utilitárias (classes estáticas) se o comportamento não pertence logicamente à classe em que está agindo
  • Não use classes de utilitário se eles modificarem o estado interno do objeto em que está agindo. A modificação do estado deve ser reservada para a hierarquia de implementação de objetos.

Métodos de extensão

  • Use a mesma decisão para métodos de extensão que faria para as aulas de utilidade quando eles criarem menos atrito. Se a adoção de métodos de extensão parecer menos natural, não faça isso.
  • Use métodos de extensão para adicionar utilitário às classes que você não tem controle (como string).
  • Não use métodos de extensão quando o comportamento for consumido pela classe que está se estendendo. Embora seja possível fazer isso, sentimentos inventado
  • Não use métodos de extensão apenas porque você pode. De fato, não se desviam do bom oop antiquado, a menos que você tem que. Quando você precisa, no entanto, os métodos de extensão são uma decisão relativamente clara e inofensiva de tomar.

Editar 2

Pensou em outro fazer para métodos de extensão

Use métodos de extensão para fornecer uma linguagem natural (DSL interna) para determinadas implementações. Aqui está um exemplo bobo.

int age = getAge();
if (age.IsDraftAge() && !age.IsLegalDrinkingAge())
{
    Console.WriteLine(@"You cannot drink until your birthdate on {0}.
Join the army instead.",
                      age.GetYearWhenGettingDrunkIsOk());
}

Outras dicas

Eu usei essa funcionalidade várias vezes - e, de fato, essa funcionalidade foi criada especificamente com o objetivo de decorar interfaces sem modificá -las, daí o LINQ. Toda a bondade que é LINQ (pelo menos para objetos) é baseada em métodos de extensão para ienumerableu003CT> .

No entanto, não sinto que os métodos de extensão de alguma forma substituam as classes base abstratas para quando você precisar eles. Os métodos de extensão não podem acessar os métodos de Estado Privado da classe estendida parecem instâncias, mas ainda são estático.

Métodos de extensão e classes base abstratas resolvem dois tipos diferentes de problemas, e a opção de usar qualquer um desses paradigmas não deve depender um do outro.

Minha resposta à sua pergunta de título é assim: Não, a existência de métodos de extensão não torna as classes base abstratas menos atraentes. Se alguém acredita que a existência de métodos de extensão torna as classes de base abstratas menos atraentes, não estava usando classes base abstratas corretamente em primeiro lugar.

Não, reduzirá algumas missUsus de classes abstratas.

Uma classe abstrata deve conter implementações/comportamentos padrão que as subclasses podem substituir. Se considerado adequadamente, isso significa que você pode substituir apenas um único comportamento da classe e trabalhar com os padrões para o resto. Os métodos de extensão fornecem algo realmente diferente a isso.

Eu gosto de métodos de extensão porque me deu a capacidade de definir o encontro (predicado), remover (predicado) etc. IList<T> que estou perdendo. Eu não acho que você possa dizer que eles substituem as classes abstratas.

Também defini métodos de extensão para adicionar comportamento genérico. Eu amo meu método de extensão de Tojson no objeto ou toxml bastante útil.

O único problema que tenho com o seu exemplo é que sempre pareço iscrentuser como uma propriedade, não um método e, infelizmente, não temos propriedades de extensão. Mas estou nitpicking

Eles não têm relação. Eu uso uma classe abstrata quando quero modelar um comportamento, que outros implementarão ou herdam.

Não, as classes abstratas não são menos atraentes. As classes abstratas fornecem o paradigma adequado para hierarquias de objetos.

Os métodos de extensão só são realmente úteis se você precisar Para adicionar métodos de instância a uma classe já existente, mas não pode modificar o código diretamente.

Os métodos de extensão são bons, mas você não pode compará -los ou seu uso com as classes abstratas. Não se esqueça do quê encapsulamento é, é um dos pilares do oop ...

Eu acho que depende do seu uso-

Se sua principal preocupação é refatorar para minimizar o número de arquivos de origem e/ou classes em uma montagem, então sim, os métodos de extensão são definitivamente o caminho a seguir, e as classes abstratas provavelmente acabarão sendo usadas menos.

No entanto, para aqueles que se preocupam mais com o que as classes abstratas representam conceitualmente, pouco mudou. Ainda faz sentido em um contexto organizacional de código para colocar "public int getCalories ()" na classe abstrata "comida", pois seria bobo para a pessoa que o come (o código usando uma subclasse de comida) para definir quantos calorias tem.

Em uma palavra: sim. Devido ao fato de que classes abstratas impõem muito às implementações futuras, o conselho geral parece ser criar classes abstratas que implementam interfaces (por exemplo, dbdatarader: iDatareader). Desde que um método não exija acesso ao estado interno de um objeto, não vejo razão para não renderizá -lo como um método de extensão. Você obtém a funcionalidade sem o custo.

Eu acho que há absolutamente casos em que essa é uma boa ideia. O LINQ é um ótimo exemplo dos benefícios, mas há outro: fluxos.

Todo o motivo dos fluxos é uma classe abstrata é porque eles tiveram que suportar métodos como BeginRead, Readbyte, etc. O fluxo pode ser uma interface, e todos esses métodos podem ser métodos de extensão. Isso possibilitaria fazer coisas como herdar a partir de uma classe não-stream e adicionar funcionalidade do fluxo e torná-lo (mais) natural adicionar métodos de fluxo potencialmente úteis, como 'o conteúdo do fluxo de despejo ao buffer de memória'.

Se você não precisar acessar campos protegidos do método de extensão, é AFAIK o caminho a seguir, pois você pode herdar várias interfaces e obter todas as extensões relacionadas dessa maneira (enquanto você só pode derivar de uma única classe abstrata).

Eu não usei nada passado .NET 2.0, então não fazia ideia de que você poderia fazer isso. Parece estranho para mim; Interfaces não são para implementações. Eu acharia isso confuso. Além disso, o exemplo que você mostra é uma classe, não uma interface.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top