Me encontré con este extraño caso ayer, donde t as D
devuelve un valor no nulo, pero (D)t
provoca un error de compilación.¿Por qué este molde no es válido cuando `x as Y` funciona bien?
Desde que estaba en un apuro que acabo de utilizar t as D
y continué, pero tengo curiosidad acerca de por qué el reparto no es válido, ya que realmente es un t
D
. ¿Alguien puede arrojar algo de luz sobre por qué al compilador no le gusta el elenco?
class Program
{
public class B<T> where T : B<T> { }
public class D : B<D> { public void M() { Console.Out.WriteLine("D.M called."); } }
static void Main() { M(new D()); }
public static void M<T>(T t) where T : B<T>
{
// Works as expected: prints "D.M called."
var d = t as D;
if (d != null)
d.M();
// Compiler error: "Cannot cast expression of type 'T' to type 'D'."
// even though t really is a D!
if (t is D)
((D)t).M();
}
}
EDIT: Jugando, creo que este es un ejemplo más claro. En ambos casos, t
tiene un límite de B
y es quizás D
. Pero el caso con el genérico no se compilará. ¿El C# simplemente ignora la restricción genérica al determinar si el elenco es legal? Incluso si lo ignora, t
podría ser un D
; Entonces, ¿por qué es esto un error de tiempo de compilación en lugar de una excepción de tiempo de ejecución?
class Program2
{
public class B { }
public class D : B { public void M() { } }
static void Main()
{
M(new D());
}
public static void M(B t)
{
// Works fine!
if (t is D)
((D)t).M();
}
public static void M<T>(T t) where T : B
{
// Compile error!
if (t is D)
((D)t).M();
}
}
Bet '(D.) (objeto) t' works –
posible duplicado de [El valor del tipo 'T' no se puede convertir a] (http://stackoverflow.com/questions/4092393/value-of-type-t-cannot-be-converted- a) –
De un comentario en [este enlace] (http://stackoverflow.com/questions/1613314/generic-type-casting-method-net) Encontré un enlace a [su respuesta] (http: // bl ogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx). Básicamente, existen algunos tipos de variables que no pueden transferirse a otros tipos (más específicamente, existen reglas sobre el casting de tipos encuadrados). Como el compilador no tiene idea de qué es T en el momento de la compilación, tiene que ir a lo seguro y rechazar el reparto. –