Ci sono alcune classi nel Framework che trasmettono effettivamente caratteristiche speciali a tutti i tipi da esse derivati ma non possiedono tali caratteristiche stesse . Lo stesso CLR non impone alcun divieto contro l'utilizzo di tali classi come vincoli, ma i tipi generici ad esse vincolati non acquisiscono le caratteristiche non ereditate come farebbero i tipi concreti. I creatori di C # hanno deciso che poiché tale comportamento potrebbe confondere alcune persone e non sono riusciti a vederne l'utilità, dovrebbero vietare tali vincoli piuttosto che consentire loro di comportarsi come fanno nel CLR.
Se, ad esempio, fosse consentito scrivere void CopyArray<T>(T dest, T source, int start, int count):; si sarebbe in grado di passare deste sourcea metodi che prevedono un argomento di tipo System.Array; inoltre, si otterrebbe una convalida in fase di compilazione che deste sourcefossero i tipi di array compatibili, ma non si sarebbe in grado di accedere agli elementi dell'array utilizzando l' []operatore.
L'incapacità di utilizzare Arraycome vincolo è per lo più abbastanza facile da aggirare, poiché void CopyArray<T>(T[] dest, T[] source, int start, int count)funzionerà in quasi tutte le situazioni in cui funzionerebbe il primo metodo. Tuttavia, ha un punto debole: il primo metodo funzionerebbe nello scenario in cui uno o entrambi gli argomenti erano di tipo System.Arrayrifiutando i casi in cui gli argomenti sono tipi di array incompatibili; l'aggiunta di un sovraccarico in cui entrambi gli argomenti erano di tipo System.Arrayfarebbe sì che il codice accetti i casi aggiuntivi che dovrebbe accettare, ma lo farebbe anche accettare erroneamente casi che non dovrebbe.
Trovo fastidiosa la decisione di mettere fuori legge la maggior parte dei vincoli speciali. L'unico che avrebbe significato semantico zero sarebbe System.Object[poiché se fosse legale come vincolo, qualsiasi cosa lo soddisferebbe]. System.ValueTypeprobabilmente non sarebbe molto utile, poiché i riferimenti di tipo ValueTypenon hanno molto in comune con i tipi di valore, ma potrebbe plausibilmente avere qualche valore nei casi che coinvolgono la riflessione. Entrambi System.Enume System.Delegateavrebbero alcuni usi reali, ma dal momento che i creatori di C # non ci hanno pensato, sono fuorilegge senza una buona ragione.