Mi sono imbattuto in questo caso strano ieri, dove t as D
restituisce un valore non nullo, ma (D)t
causa un errore del compilatore.Perché questo cast non è valido quando `x as Y` funziona correttamente?
Da quando ero in fretta ho appena usato t as D
e portato avanti, ma sono curioso di sapere il motivo per cui il cast non è valido, come t
è davvero un D
. Qualcuno può far luce sul motivo per cui al compilatore non piace il cast?
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: Giocare in giro, credo che questo è un esempio chiaro. In entrambi i casi, t
è limitato a B
ed è forse un D
. Ma il caso con il generico non verrà compilato. Il C# ignora semplicemente il vincolo generico per determinare se il cast è legale? Anche se lo ignora, t
potrebbe ancora essere un D
; quindi, perché questo è un errore di tempo di compilazione invece di un'eccezione di runtime?
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) (oggetto) t' works –
possibile duplicato di [Valore di tipo 'T' non può essere convertito in] (http://stackoverflow.com/questions/4092393/valore-di-tipo-t-cannot-be-converted- a) –
Da un commento in [questo collegamento] (http://stackoverflow.com/questions/1613314/generic-type-casting-method-net) Ho trovato un collegamento a [risposta] (http: // bl ogs.msdn.com/b/ericlippert/archive/2009/03/19/representation-and-identity.aspx). Essenzialmente, ci sono alcuni tipi di variabili che non possono essere castati ad altri tipi (più specificamente ci sono delle regole sul casting dei tipi di box). Dato che il compilatore non ha idea di cosa T sia in fase di compilazione, deve giocare sul sicuro e negare il cast. –