Я подозреваю, что причина, по которой enum
не принимается в качестве общего ограничения, заключается в том, что хотя есть некоторые вещи, которые можно «ожидать» сделать с параметром с ограничением на перечисление, чего нельзя сделать с неограниченным параметр, единственный, который действительно будет работать, будет вызывать очень медленный неуниверсальный HasFlag
; в частности, операции, которые включают преобразование между перечислением и связанным с ним базовым типом, не могут быть использованы. Разрешение ограничения, которое не позволяло бы программистам использовать переменные так, как они ожидали, а только добавляло возможность вызывать ужасно медленный неуниверсальный метод, казалось не стоящим.
Как таковая, я не думаю, что невозможность использовать Enum
в качестве ограничения типа была бы потерей, но для добавления функции, которая не ожидалась, когда было принято решение: методы расширения и их взаимодействие с Intellisense. Если записать метод bool FlagCheck.HasAnyFlags<T>(T enum1, T enum2) where T:struct
, который принимает два перечисления совпадающего типа и проверяет, содержит ли один флаги, которые также находятся в другом [можно написать такой метод примерно на порядок быстрее, чем Enum.HasFlag
], он может Не имеет смысла вызывать его для параметров типа double
, но единственным следствием этого является то, что такие вещи будут перехватываться во время выполнения, а не во время компиляции. Только если кто-то делает такую вещь методом расширения, отсутствие ограничения перечисления становится раздражающим; в этом случае это означает, что у Intellisense нет возможности предложить HasAnyFlags
для переменной типа enum
без ее появления и для переменных других типов.
Кстати, я думаю, что я не согласен с философией ограничений enum
по той же причине, по которой я не согласен с правилом, согласно которому нельзя ограничиваться закрытым типом. Даже если было бы бесполезно создавать универсальный параметр типа, который был бы ограничен типом, который всегда был бы запечатан, тот факт, что тип запечатан в [возможно предварительной] версии сборки, подразумевает, что это всегда будет так. Кроме того, если тип незапечатан, но имеет только конструкторы internal
[вызываются с помощью фабричных методов], я не знаю, что замена его на запечатанный класс будет серьезным изменением , но для правила об ограничениях запечатанного типа .