Mientras revisaba algún código, noté la oportunidad de cambiarlo para usar genéricos. El código (ofuscado) se ve así:
public void DoAllTheThings(Type typeOfTarget, object[] possibleTargets)
{
var someProperty = typeOfTarget.GetProperty(possibleTargets[0]);
...
}
Este código podría ser reemplazado por genéricos, así:
public void DoAllTheThings<T>(object[] possibleTargets[0])
{
var someProperty = type(T).getProperty(possibleTargets[0]);
...
}
Al investigar los beneficios y las deficiencias de este enfoque, encontré un término llamado abuso genérico . Ver:
- Proteger a los no iniciados (desarrollador) de los genéricos
- https://stackoverflow.com/questions/28203199/is-this-an-abuse-of-generics
- https://codereview.stackexchange.com/q/60695
Mi pregunta viene en dos partes:
- ¿Hay algún beneficio en pasar a genéricos como este? (¿Rendimiento? ¿Legibilidad?)
- ¿Qué es el abuso genérico? ¿Y el uso de un genérico cada vez que hay un parámetro de tipo es un abuso ?
Respuestas:
Cuando los genéricos se aplican adecuadamente, eliminan el código en lugar de simplemente reorganizarlo. Principalmente, el código que los genéricos son mejores para eliminar son los tipos de letra, la reflexión y la escritura dinámica. Por lo tanto, el abuso de genéricos podría definirse libremente como la creación de código genérico sin una reducción significativa en la tipificación, reflexión o tipeo dinámico en comparación con una implementación no genérica.
Con respecto a su ejemplo, esperaría un uso apropiado de los genéricos para cambiarlo
object[]
a unoT[]
o similar, y evitarloType
o portype
completo. Eso podría requerir una refactorización significativa en otros lugares, pero si el uso de genéricos es apropiado en este caso, debería terminar siendo más simple en general cuando haya terminado.fuente
object[]
aT[]
.Usaría la regla sin sentido: los genéricos, como todas las otras construcciones de programación, existen para resolver un problema . Si no hay ningún problema para resolver los genéricos, usarlos es abuso.
En el caso específico de los genéricos, en su mayoría existen para abstraerse de tipos concretos, lo que permite que las implementaciones de código para los diferentes tipos se plieguen en una plantilla genérica (o como lo llame su idioma). Ahora, suponga que tiene un código que usa un tipo
Foo
. Puede reemplazar ese tipo con un genéricoT
, pero si solo necesita ese código para trabajarFoo
, simplemente no hay otro código con el que pueda plegarlo. Por lo tanto, no existe ningún problema para resolver, por lo que la indirecta de agregar el genérico solo serviría para reducir la legibilidad.En consecuencia, sugeriría simplemente escribir el código sin usar genéricos, hasta que vea la necesidad de introducirlos (porque necesita una segunda instanciación). Entonces, y solo entonces, es el momento de refactorizar el código para usar genéricos. Cualquier uso antes de ese punto es abuso en mis ojos.
Esto parece sonar demasiado pedante, así que permíteme recordarte:
no hay una regla sin excepciones en la programación. Esta regla incluida.
fuente
El código se ve extraño. Pero si lo estamos llamando, parece mejor especificar el tipo como genérico.
https://stackoverflow.com/questions/10955579/passing-just-a-type-as-a-parameter-in-c-sharp
Personalmente, no me gustan estas contorsiones que hacen que el código de llamada se vea bonito. por ejemplo, todo lo 'fluido' y los métodos de extensión.
Pero tienes que admitir que tiene un seguimiento popular. incluso Microsoft lo usa en la unidad, por ejemplo
fuente
Para mí, parece que estabas en el camino correcto aquí, pero no terminaste el trabajo.
¿Has considerado cambiar el
object[]
parámetroFunc<T,object>[]
para el siguiente paso?fuente