Ao revisar 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 deficiências dessa abordagem, encontrei um termo chamado abuso genérico . Vejo:
- Protegendo os não iniciados (desenvolvedor) de genéricos
- https://stackoverflow.com/questions/28203199/is-this-an-abuse-of-generics
- https://codereview.stackexchange.com/q/60695
Minha pergunta vem em duas partes:
- Existem benefícios em mudar para genéricos como esse? (Desempenho? Legibilidade?)
- O que é abuso de genéricos? E está usando um genérico toda vez que há um parâmetro de tipo um abuso ?
Respostas:
Quando os genéricos são aplicados adequadamente, eles removem o código em vez de apenas reorganizá-lo. Principalmente, o código que os genéricos são melhores para remover é tipografia, reflexão e digitação dinâmica. Portanto, o abuso de genéricos pode ser definido livremente como a criação de código genérico sem redução significativa na conversão de tipo, 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 que um uso apropriado de genéricos alterasse a
object[]
para aT[]
ou similar e evitasseType
outype
completamente. Isso pode exigir uma refatoração significativa em outro lugar, mas se o uso de genéricos for apropriado nesse caso, ele deverá terminar mais simples quando terminar.fonte
object[]
paraT[]
.Eu usaria a regra no-nonsense: os genéricos, como todas as outras construções de programação, existem para resolver um problema . Se não houver problema para resolver os genéricos, usá-los é abuso.
No caso específico dos genéricos, eles existem principalmente para se afastar de tipos concretos, permitindo que as implementações de código para os diferentes tipos sejam dobradas em um modelo genérico (ou seja como for que seu idioma o chamar). Agora, suponha que você tenha um código que use um tipo
Foo
. Você pode substituir esse tipo por um genéricoT
, mas se você precisar desse código apenas para trabalharFoo
, simplesmente não há outro código com o qual você possa dobrá-lo. Portanto, não existe nenhum problema a ser resolvido; portanto, o indireto de adicionar o genérico serviria apenas para reduzir a legibilidade.Consequentemente, sugiro apenas escrever o código sem usar genéricos, até que seja necessário apresentá-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 soar pedante demais, então, lembre-se:
não há regra sem exceções na programação. Esta regra incluída.
fonte
O código parece estranho. Mas, se estivermos chamando, parece melhor especificar o tipo como genérico.
https://stackoverflow.com/questions/10955579/passing-just-a-type-as-a-parameter-in-c-sharp
Pessoalmente, não gosto dessas contorções que tornam o código de chamada bonito. por exemplo, a coisa toda 'fluente' e os métodos de extensão.
Mas você tem que admitir que tem seguidores populares. até a microsoft usa-o em unidade, por exemplo
fonte
Para mim, parece que você estava no caminho certo aqui, mas não terminou o trabalho.
Você já pensou em alterar o
object[]
parâmetroFunc<T,object>[]
para a próxima etapa?fonte