В 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 # не думали о них, они объявлены вне закона без уважительной причины.