У Рамці є певні класи, які фактично передають особливі характеристики всім похідним від них типам, але самі не володіють цими характеристиками . 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 # не думали про них, вони заборонені без поважних причин.