La domanda specifica, perché non si può fare questo:
public class MyGenericClass<T> : T
E si può fare questo:
public class MyGenericClass<T>
{
T obj;
}
La ragione è che il CLR piace essere in grado di compilare un singolo versione del codice per MyGenericClass che funzionerà per qualsiasi tipo di riferimento specificato per T.
Può farlo per il secondo caso, perché può tranquillamente sostituire T
con object
e inserire calchi del caso, più o meno equivalente a:
public class MyGenericClass
{
object obj;
}
Ma per la versione eredità, quel trucco non funziona.
Inoltre, molte strutture utili sarebbero impossibili da descrivere attraverso i vincoli di interfaccia. Quando si eredita da un tipo, si può fare molto di più che chiamare semplicemente i metodi su di esso - è anche possibile sovrascriverli. Considerate questo esempio ipotetico:
class MyBase
{
public virtual void MyVirtual() { }
}
class MyGenericDerived<T> : T
{
public override void MyVirtual()
{
Console.WriteLine("Overridden!");
}
}
MyBase obj = new MyGenericDerived<MyBase>();
obj.MyVirtual();
Quello che voglio fare c'è qualcosa come un "mix-in", dove MyGenericDerived fornisce le definizioni per le funzioni virtuali in qualunque base di esso viene applicato. Ma come fa il compilatore a sapere che T avrà un metodo chiamato MyVirtual che può essere sovrascritto? Avrei bisogno di mettere un limite su T. Come potrei esprimerlo attraverso le interfacce? È impossibile. Utilizzare le interfacce per descrivere i vincoli non è una soluzione adeguata una volta che si consente l'ereditarietà dei parametri di tipo. Quindi questa è un'altra ragione per cui oggi non esiste nella lingua.
fonte
2009-04-14 19:35:32
qual è la tua motivazione per provare a farlo? –
Attendi il tipo dinamico in C# 4.0. –