what - ¿Cuáles son las características de rendimiento de la reflexión ''es'' en C#?
system.reflection c# (4)
"is" es básicamente equivalente al operador de IL "isinst", que ese artículo describe como rápido.
Esta pregunta ya tiene una respuesta aquí:
- C # ''es'' operador rendimiento 8 respuestas
Se muestra que "como" el lanzamiento es mucho más rápido que el lanzamiento del prefijo, pero ¿qué pasa con el reflejo ''es''? ¿Qué tan malo es? Como se puede imaginar, buscar ''es'' en Google no es tremendamente efectivo.
Debe ser lo suficientemente rápido como para no importar. Si está comprobando el tipo de objeto lo suficiente como para que tenga un impacto notable en el rendimiento, debe replantearse su diseño.
Hay algunas opciones:
- El elenco clásico :
Foo foo = (Foo)bar
- El operador de reparto :
Foo foo = bar as Foo
- La prueba
is
:bool is = bar is Foo
- El elenco clásico necesita comprobar si la
bar
se puede convertir aFoo
(rápida) con seguridad, y luego hacerlo (más lento), o lanzar una excepción (muy lento). - El operador
as
necesita comprobar si se puede lanzar labar
, luego hacer el molde, o si no se puede lanzar con seguridad, entonces simplemente devuelvenull
. - El operador
is
simplemente comprueba si labar
se puede convertir a Foo y devuelve un valorboolean
.
La prueba is es rápida, porque solo realiza la primera parte de una operación de lanzamiento completo. El operador as
es más rápido que un elenco clásico porque no lanza una excepción si el lanzamiento falla (lo que lo hace bueno para situaciones en las que legítimamente esperas que el lanzamiento falle).
Si solo necesita saber si la bar
variable es un Foo
entonces use el operador is
, PERO , si va a probar si la bar
es un Foo
, y si es así, entonces empújela , entonces debe usar el operador as
.
Esencialmente, cada lanzamiento debe hacer el equivalente de un cheque interno internamente, para garantizar que el lanzamiento sea válido. Entonces, si haces una verificación de is
seguido de un reparto completo (ya sea as
elenco o con el operador de reparto clásico) estás haciendo efectivamente la prueba is
dos veces, lo cual es un gasto extra adicional.
La forma en que lo aprendí es que esto:
if (obj is Foo) {
Foo f = (Foo)obj;
f.doSomething();
}
es más lento que esto:
Foo f = obj as Foo;
if (f != null) {
f.doSomething();
}
¿Es lo suficientemente lento como para importar? Probablemente no, pero es tan simple prestarle atención, que es mejor que lo hagas.