O que é abuso de genéricos?

36

Durante a revisão de algum código, notei a oportunidade de alterá-lo para usar genéricos. O código (ofuscado) se parece com:

public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
    var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
    ...
}

Este código pode ser substituído por genéricos, da seguinte forma:

public void DoAllTheThings<T>(object[] possibleTargets[0])
{
    var someProperty = type(T).getProperty(possibleTargets[0]);
    ...
}

Ao pesquisar os benefícios e as deficiências dessa abordagem, encontrei um termo chamado abuso genérico . Veja:

Minha pergunta vem em duas partes:

  1. Há algum benefício em migrar para genéricos como esse? (Desempenho? Legibilidade?)
  2. O que é o abuso de genéricos? E está usando um genérico toda vez que há um parâmetro de tipo um abuso ?
por SyntaxRules 07.02.2018 / 18:23
fonte

4 respostas

88

Quando os genéricos são aplicados apropriadamente, eles removem o código, em vez de apenas rearranjá-lo. Primeiramente, o código que os genéricos são melhor em remover é typecasts, reflexão e digitação dinâmica. Portanto, o abuso de genéricos pode ser vagamente definido como a criação de código genérico sem redução significativa na tipografia, reflexão ou digitação dinâmica em comparação com uma implementação não genérica.

Em relação ao seu exemplo, eu esperaria um uso adequado de genéricos para alterar o object[] para um T[] ou similar e evitar Type ou type . Isso pode exigir uma refatoração significativa em outro lugar, mas se você usar genéricos nesse caso, ele deverá ficar mais simples quando estiver pronto.

    
por 07.02.2018 / 19:59
fonte
5

Eu usaria a regra no-nonsense: Generics, como todas as outras construções de programação, existem para resolver um problema . Se não houver nenhum problema para resolver para genéricos, usá-los é abuso.

No caso específico dos genéricos, eles existem principalmente para abstrair os tipos concretos, permitindo que as implementações de código para os diferentes tipos sejam agrupadas em um modelo genérico (ou qualquer que seja a sua linguagem para chamá-lo). Agora, suponha que você tenha um código que use um tipo Foo . Você pode substituir esse tipo por um genérico T , mas se você só precisar desse código para trabalhar com Foo , simplesmente não haverá outro código com o qual você possa juntá-lo. Assim, nenhum problema existe para ser resolvido, então a indirecção de adicionar o genérico serve apenas para reduzir a legibilidade.

Consequentemente, sugiro apenas escrever o código sem usar genéricos, até que você veja a necessidade de introduzi-los (porque você precisa de uma segunda instanciação). Então, e somente então, é a hora de refatorar o código para usar genéricos. Qualquer uso antes desse ponto é abuso aos meus olhos.

Isso parece um pouco pedante demais, então deixe-me lembrá-lo:
Não há regra sem exceções na programação. Esta regra incluiu.

    
por 08.02.2018 / 00:02
fonte
0

O código parece estranho. Mas se estamos chamando, parece melhor especificar o tipo como genérico.

link

Pessoalmente, não gosto dessas contorções que fazem o código de chamada parecer bonito. por exemplo, toda a coisa 'fluente' e métodos de extensão.

Mas você tem que admitir que tem seguidores populares. mesmo microsoft usá-lo em unidade por exemplo

container.RegisterType<IInterface,Concrete>()
    
por 07.02.2018 / 18:53
fonte
0

Para mim, parece que você estava no caminho certo aqui, mas não terminou o trabalho.

Você já pensou em alterar o parâmetro object[] para Func<T,object>[] na próxima etapa?

    
por 01.03.2018 / 21:46
fonte

Tags