В Framework есть определенные классы, которые эффективно передают особые характеристики всем производным от них типам, но сами не обладают этими характеристиками. . Сама среда CLR не налагает запрета на использование этих классов в качестве ограничений, но связанные с ними универсальные типы не будут приобретать ненаследуемые характеристики, как конкретные типы. Создатели C # решили, что, поскольку такое поведение может сбить с толку некоторых людей, и они не видели в нем какой-либо полезности, им следует запретить такие ограничения, а не позволить им вести себя так, как они делают в среде CLR.
Если, например, разрешено писать void CopyArray<T>(T dest, T source, int start, int count):; можно было бы передать destи sourceметодам, которые ожидают аргумент типа System.Array; кроме того, можно было бы получить проверку во время компиляции, которые destи sourceбыли совместимыми типами массивов, но нельзя было бы получить доступ к элементам массива с помощью[] оператора.
Невозможность использования Arrayв качестве ограничения в большинстве случаев довольно легко обойти, поскольку void CopyArray<T>(T[] dest, T[] source, int start, int count)будет работать почти во всех ситуациях, когда будет работать первый метод. Однако у него есть слабость: первый метод будет работать в сценарии, в котором один или оба аргумента имеют тип, System.Arrayпри этом отклоняются случаи, когда аргументы являются несовместимыми типами массивов; добавление перегрузки, в которой оба аргумента имеют тип System.Array, заставит код принимать дополнительные случаи, которые он должен принимать, но также заставит его ошибочно принимать случаи, которые он не должен принимать.
Я считаю решение объявить вне закона большинство специальных ограничений утомительным. Единственным, у которого было бы нулевое семантическое значение, было бы System.Object[поскольку, если бы это было законным как ограничение, ему удовлетворяло бы что угодно]. System.ValueTypeвероятно, было бы не очень полезно, поскольку ссылки типа на ValueTypeсамом деле не имеют много общего с типами значений, но они могут иметь какое-то значение в случаях, связанных с отражением. Оба System.Enumи System.Delegateбудут иметь какое-то реальное применение, но поскольку создатели C # не думали о них, они объявлены вне закона без уважительной причины.