Teniendo en cuenta que este es un caso de uso muy natural (si usted no sabe lo que realmente hace as
),¿Por qué se 'implementa' como 'como'?
if (x is Bar) {
Bar y = x as Bar;
something();
}
es efectivamente equivalente (es decir, el compilador genera CIL en el código anterior será equivalente) a:
Bar y = x as Bar;
if (y != null) {
y = x as Bar; //The conversion is done twice!
something();
}
EDIT:
supongo que no había hecho mi pregunta clara. Nunca escribiría el segundo fragmento ya que, por supuesto, es redundante. Estoy afirmando que el CIL generado por el compilador al compilar el primer fragmento es equivalente al segundo fragmento, que es redundante. Preguntas: a) ¿Es esto correcto? b) Si es así, ¿por qué se implementa is
así?
Esto es porque creo que el primer fragmento mucho más claro y más bonita que la realidad bien escrito-
Bar y = x as Bar;
if (y != null) {
something();
}
CONCLUSIÓN:
Optimizar el caso is
/as
no es responsabilidad del compilador, pero los JIT.
También, como con un nulo comprobar que tiene menos (y menos caro) instrucciones que ambas de las alternativas (is
y as
y is
y cast
).
Adición:
CIL para como con nullcheck (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: stloc.0
L_0008: ldloc.0
L_0009: ldnull
L_000a: ceq
L_000c: stloc.1
L_000d: ldloc.1
L_000e: brtrue.s L_0019
L_0011: ldarg.0
L_0019: ret
CIL para es y fundido (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: ldnull
L_0008: cgt.un
L_000a: ldc.i4.0
L_000b: ceq
L_000d: stloc.1
L_000e: ldloc.1
L_000f: brtrue.s L_0021
L_0012: ldarg.1
L_0013: castclass string
L_0018: stloc.0
L_0019: ldarg.0
L_0021: ret
CIL para es y como (.NET 3.5):
L_0001: ldarg.1
L_0002: isinst string
L_0007: ldnull
L_0008: cgt.un
L_000a: ldc.i4.0
L_000b: ceq
L_000d: stloc.1
L_000e: ldloc.1
L_000f: brtrue.s L_0021
L_0012: ldarg.1
L_0013: isinst string
L_0018: stloc.0
L_0019: ldarg.0
L_0021: ret
Estos han sido editados por brevedad (declaraciones de método, nops y llamadas a algo() eliminado).
No lo llamaría un caso de uso típico, más típico sería Bar y = x como Bar; if (y! = null) {do_stuff(); }. Si usa _as_ de todos modos, ¿por qué verificar con _es_ primero? – dbemerlin
@dbemerlin: Porque el primer fragmento es mucho más natural y agradable en los ojos que el segundo. Este es exactamente mi punto. –
El primero me dice que fue escrito por alguien que no sabe lo que dice 'as', para ser honesto. – AakashM