Existem certas classes na Estrutura que efetivamente transmitem características especiais para todos os tipos derivados delas, mas não possuem essas características . O próprio CLR não impõe nenhuma proibição contra o uso dessas classes como restrições, mas os tipos genéricos restritos a elas não adquiririam as características não herdadas da mesma forma que os tipos concretos. Os criadores do C # decidiram que, como esse comportamento pode confundir algumas pessoas, e eles deixaram de ver qualquer utilidade nele, eles deveriam proibir essas restrições em vez de permitir que se comportassem como o fazem no CLR.
Se, por exemplo, alguém pudesse escrever void CopyArray<T>(T dest, T source, int start, int count)
:; seria possível passar dest
e source
para métodos que esperam um argumento do tipo System.Array
; além disso, seria possível obter a validação em tempo de compilação de que dest
e source
eram os tipos de array compatíveis, mas não seria capaz de acessar elementos do array usando o []
operador.
A incapacidade de usar Array
como uma restrição é muito fácil de contornar, uma vez void CopyArray<T>(T[] dest, T[] source, int start, int count)
que funcionará em quase todas as situações em que o método anterior funcionaria. No entanto, ele tem uma fraqueza: o método anterior funcionaria no cenário em que um ou ambos os argumentos fossem do tipo, System.Array
ao mesmo tempo que rejeitava casos em que os argumentos eram tipos de array incompatíveis; adicionar uma sobrecarga onde ambos os argumentos fossem do tipo System.Array
faria o código aceitar os casos adicionais que deveria aceitar, mas também faria com que ele aceitasse erroneamente os casos que não deveria.
Acho a decisão de proibir a maioria das restrições especiais cansativa. O único que teria significado semântico zero seria System.Object
[já que se isso fosse legal como uma restrição, qualquer coisa iria satisfazê-lo]. System.ValueType
provavelmente não seria muito útil, uma vez que as referências de tipo ValueType
não têm muito em comum com os tipos de valor, mas pode plausivelmente ter algum valor em casos envolvendo Reflexão. Ambos System.Enum
e System.Delegate
teriam alguns usos reais, mas como os criadores do C # não pensaram neles, eles são proibidos sem um bom motivo.