Supongamos que tengo un método genérico:¿Por qué el casting proporciona CS0030, mientras que "as" funciona?
T Foo(T x) {
return x;
}
Hasta aquí todo bien. Pero quiero hacer algo especial si es un Hashtable. (Sé que esto es un ejemplo completamente artificial. Foo()
no es un método muy emocionante, ya sea. El juego.)
if (typeof(T) == typeof(Hashtable)) {
var h = ((Hashtable)x); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
}
Darn. Para ser justos, no puedo decir si esto debería ser legal C# o no. Bueno, ¿y si trato de hacerlo de otra manera?
if (typeof(T) == typeof(Hashtable)) {
var h = x as Hashtable; // works (and no, h isn't null)
}
Eso es un poco raro. De acuerdo con MSDN, expression as Type
es (excepto para evaluar la expresión dos veces) lo mismo que expression is type ? (type)expression : (type)null
.
¿Qué ocurre si trato de usar la expresión equivalente de los documentos?
if (typeof(T) == typeof(Hashtable)) {
var h = (x is Hashtable ? (Hashtable)x : (Hashtable)null); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
}
La única diferencia entre la fundición y documentado as
que veo es "el operador as
sólo realiza las conversiones de referencia y las conversiones de boxeo". Tal vez necesito decir que estoy usando un tipo de referencia?
T Foo(T x) where T : class {
var h = ((Hashtable)x); // CS0030: Cannot convert type 'T' to 'System.Collections.Hashtable'
return x;
}
¿Qué está pasando? ¿Por qué as
funciona bien, mientras que el lanzamiento ni siquiera se compila? ¿Debería funcionar el elenco, o el as
no funciona, o hay alguna otra diferencia de idioma entre la conversión y as
que no se encuentra en estos documentos de MSDN que encontré?
Estoy bastante seguro de que la frase que está citando de MSDN existía antes que los genéricos. –
Aún así, si eso es todo lo que hay ... ¡Interesante pregunta! – Blindy
¿Es esto un engaño, o simplemente relacionado de cerca: http://stackoverflow.com/questions/884315/how-to-up-cast-to-a-generic-object? –