Спецификация CLS
Для полного взаимодействия с другими объектами независимо от языка реализации необходимо, чтобы объекты предоставляли вызывающим объектам только те функциональные возможности, которые являются общими для всех языков, с которыми они будут взаимодействовать. Для этого была создана спецификация CLS, которая является набором основных функциональных возможностей языка, применяемых во многих приложениях. Правила CLS составляют подмножество Система общих типов CTS, таким образом, все правила, которые применяются к системе общих типов, применяются и к CLS, за исключением тех случаев, когда в CLS определены более строгие правила. Спецификация CLS обеспечивает расширенное и надежное взаимодействие языков, определяя набор функциональных возможностей, доступных разработчикам в разных языках. В CLS также устанавливаются требования к CLS-совместимости, которые позволяют проверять, соответствует ли управляемый код спецификации CLS, и определять для конкретного средства уровень поддержки разработки управляемого кода, в котором используются функциональные возможности CLS.
Если в API-интерфейсе компонента, который предоставляется другому коду, используются только функциональные возможности CLS (включая производные классы), использовать компонент можно будет в любом языке программирования, поддерживающем CLS. Компоненты, которые соответствуют правилам CLS и используют только включенные в CLS функциональные возможности, называются CLS-совместимыми компонентами.
Большинство членов, определенных в типах в разделе Библиотека классов платформы .NET Framework, являются CLS-совместимыми. Однако некоторые типы в библиотеке классов могут содержать CLS-несовместимые члены. Эти члены обеспечивают поддержку языковых возможностей, отсутствующих в CLS. В справочной документации указываются типы и члены, несовместимые с CLS, и для них всегда доступен альтернативный вариант, совместимый с CLS. Дополнительные сведения о типах в библиотеке классов .NET Framework см. в разделе Библиотека классов платформы .NET Framework.
Спецификация CLS достаточно велика, чтобы содержать языковые конструкции, часто используемые разработчиками, и, в то же время, достаточно компактна, чтобы ее поддерживало большинство языков. Кроме того, из CLS были исключены все языковые конструкции, для которых невозможно выполнить быструю проверку на строгую типизацию кода, чтобы при необходимости на всех CLS-совместимых языках можно было создавать код, поддающийся проверке. Дополнительные сведения о проверке на строгую типизацию см в разделе Процесс управляемого выполнения.
В следующей таблице приводится сводка по функциональным возможностям, вошедшим в CLS, и указывается, доступна ли функциональная возможность разработчикам и компиляторам ("Везде") или только компиляторам. Таблица содержит общие, но не исчерпывающие сведения. Дополнительные сведения см. в спецификации для CLI (раздел I) на веб-сайте Microsoft Developer Network (MSDN).
Функция |
Применение |
Описание |
---|---|---|
Общие |
|
|
Видимость |
Все |
Правила CLS применяются только к тем составляющим типа, которые представлены вне определяющей сборки. |
Глобальные члены |
Все |
Глобальные статические (static) поля и методы не совместимы с CLS. |
Именование |
|
|
Символы и регистры |
Все |
CLS-совместимые языковые компиляторы должны подчиняться правилам 7-го дополнения 15-го технического доклада Юникода 3.0, где определяется набор символов, которые могут использоваться в идентификаторах и в качестве первых символов идентификаторов. Описание этого стандарта находится на веб-узле Консорциума Юникод. Два идентификатора различаются, если различия между ними не сводятся к различиям в регистре. |
Ключевые слова |
Компиляторы |
CLS-совместимые языковые компиляторы поддерживают механизм ссылок на идентификаторы, совпадающие с ключевыми словами. CLS-совместимые языковые компиляторы предоставляют механизм определения и переопределения виртуальных методов с именами, совпадающими с ключевыми словами в языке. |
Уникальность |
Все |
Все имена, используемые в CLS-совместимой области, должны различаться, даже если они относятся к двум различным видам членов, за исключением тех случаев, когда имена идентичны и разрешаются посредством перегрузки. Например, CLS запрещает использование одинаковых имен для метода и поля в отдельном типе. |
Сигнатуры |
Все |
Все возвращаемые и параметрические типы, фигурирующие в сигнатуре типа или члена, должны быть CLS-совместимыми. |
Типы |
|
|
Простые типы |
Все |
Библиотека классов платформы .NET Framework содержит типы, соответствующие простым типам данных, используемым компиляторами. Из этих типов CLS-совместимыми являются: Byte, Int16, Int32, Int64, Single, Double, Boolean, Char, Decimal, IntPtr и String. Дополнительные сведения об этих типах см. в таблице типов в разделе Библиотека классов платформы .NET Framework. |
Упакованные типы |
Все |
Типы упакованных значений (типы значений, преобразованные в объекты) не входят в CLS. Вместо этого следует использовать System.Object System.ValueType или System.Enum. |
Видимость |
Все |
Объявления типов и членов не должны содержать типы с меньшей видимостью или доступностью, чем у объявляемого типа или члена. |
Методы интерфейса |
Компиляторы |
CLS-совместимые языковые компиляторы должны иметь специальные синтаксические конструкции для случаев, когда в одном типе реализуется два интерфейса и для каждого требуется определить метод с одним и тем же именем и сигнатурой. Такие методы должны считаться разными и не обязательно должны иметь одинаковую реализацию. |
Закрытие |
Все |
Отдельные члены CLS-совместимых интерфейсов и абстрактных классов должны быть объявлены CLS-совместимыми. |
Вызов конструктора |
Все |
Чтобы получить доступ к любым унаследованным данным экземпляра, конструктор должен вызвать конструктор базового класса. |
Типизированные ссылки |
Все |
Типизированные ссылки несовместимы с CLS. (Типизированная ссылка — это особая конструкция, содержащая ссылки на объект и на тип. Типизированные ссылки предоставляют возможность поддержки C++ в среде CLR для методов с переменным числом аргументов.) |
Члены типов |
|
|
Перегрузка |
Все |
Перегрузка разрешена для индексированных свойств, методов и конструкторов. Для полей и событий перегрузка запрещена. Свойства нельзя перегружать по типу (то есть по возвращаемому типу метода получения), но допускается перегрузка свойств с другим числом или другими типами индексов. Методы можно перегружать только на основе числа и типов их параметров, а в случае универсальных методов — на основе числа их универсальных параметров. Перегрузка операторов не входит в CLS. Однако в CLS содержатся инструкции по предоставлению понятных имен (например, Add()) и заданию разряда в метаданных. Компиляторы, поддерживающие перегрузку операторов, могут следовать этим инструкциям, но это не обязательно. |
Уникальность перегруженных членов |
Все |
Поля и вложенные типы должны различаться только идентификатором. Методы, свойства и события с одинаковыми именами (при сравнении идентификаторов) должны различаться не только возвращаемым типом. |
Операторы преобразования |
Все |
Если оператор op_Implicit или op_Explicit перегружен по возвращаемому типу, необходимо предоставить альтернативный способ преобразования. |
Методы |
|
|
Доступность переопределенных методов |
Все |
При переопределении унаследованных методов доступность не должна изменяться, кроме случаев переопределения метода, унаследованного из другой сборки с доступностью FamilyOrAssembly. В таких случаях переопределенный метод должен иметь доступность Family. |
Списки аргументов |
Все |
CLS поддерживает только одно соглашение по вызову — стандартное соглашение по управляемым вызовам. Списки аргументов с переменной длиной запрещены. (Для поддержки переменного числа аргументов в Microsoft Visual Basic используется зарезервированное слово ParamArray, а в C# — ключевое слово params.) |
Свойства |
|
|
Метаданные объекта доступа к данным |
Компиляторы |
Методы получения и установки значения, реализующие методы свойства, отмечаются в метаданных идентификатором mdSpecialName. |
Модификаторы |
Все |
Свойство и средства доступа к нему должны быть либо статическими (static), либо виртуальными (virtual), либо свойствами экземпляра (instance). |
Имена объектов доступа к данным |
Все |
Свойства должны соответствовать специальным шаблонам именования. Если для свойства Name определен метод получения, он называется get_Name; если для него определен метод установки, он называется set_Name. |
Возвращаемый тип и аргументы |
Все |
Тип свойства равен типу возвращаемого значения метода получения и типу последнего аргумента метода установки. Типы параметров свойства равны типам параметров метода получения и типам всех параметров метода установки, за исключением последнего. Все эти типы должны быть CLS-совместимыми и не могут быть управляемыми указателями, их нельзя передавать по ссылке. |
События |
|
|
Методы событий |
Все |
Методы добавления и удаления события должны либо оба присутствовать, либо оба отсутствовать. |
Метаданные метода события |
Компиляторы |
Методы, реализующие событие, должны отмечаться в метаданных идентификатором mdSpecialName. |
Доступность объекта доступа к данным |
Все |
Доступность методов добавления, удаления и вызова события должна быть одинаковой. |
Модификаторы |
Все |
Методы для добавления, удаления и вызова события должны быть либо статическими (static), либо виртуальными (virtual), либо методами экземпляра (instance). |
Имена методов событий |
Все |
События должны соответствовать специальным шаблонам именования. Если для события MyEvent определен метод добавления, он называется add_MyEvent, если определен метод удаления, он называется remove_MyEvent, а метод вызова события называется raise_MyEvent. |
Аргументы |
Все |
Методы для добавления и удаления события должны получать один параметр, тип которого определяет тип события, и этот тип должен быть производным от System.Delegate. |
Типы указателей |
|
|
Указатели |
Все |
Типы указателей и типы указателей функций несовместимы с CLS. |
интерфейсов, |
|
|
Сигнатуры членов |
Все |
CLS-совместимые интерфейсы не должны требовать определение CLS-несовместимых методов для их реализации. |
Модификаторы членов |
Все |
CLS-совместимые интерфейсы не могут определять ни статические методы, ни поля. Они могут определять свойства, события и виртуальные методы. |
Ссылочные типы |
|
|
Вызов конструктора |
Все |
Конструкторы объектов вызываются для ссылочных типов только в ходе создания объекта, а инициализация объектов выполняется только один раз. |
Типы классов |
|
|
Наследование |
Все |
CLS-совместимый класс должен наследоваться от CLS-совместимого класса (System.Object является CLS-совместимым). |
Массивы1 |
|
|
Типы элементов |
Все |
Элементы массива должны относиться к CLS-совместимым типам. |
Измерения |
Все |
Массив должен иметь фиксированное число измерений больше нуля. |
Границы |
Все |
Нижняя граница всех измерений массива должна быть равна нулю. |
Перечисления |
|
|
Базовый тип |
Все |
Базовый тип перечисления должен быть встроенным целочисленным типом CLS (Byte, Int16 Int32 или Int64). |
FlagsAttribute |
Компиляторы |
Наличие пользовательского атрибута System.FlagsAttribute в определении перечисления указывает на то, что перечисление должно рассматриваться как набор битовых полей (флагов), а отсутствие этого атрибута указывает на то, что тип следует рассматривать как группу перечисленных констант. В языках рекомендуется использовать атрибут FlagsAttribute или особый синтаксис для различения этих двух типов перечислений. |
Члены поля |
Все |
Статические (static) поля литералов перечисления должны относиться к тому же типу, что и тип самого перечисления. |
Исключения |
|
|
Наследование |
Все |
Объекты исключений должны иметь тип System.Exception или наследоваться от System.Exception. |
Пользовательские атрибуты |
|
|
Кодировки значений |
Компиляторы |
CLS-совместимые компиляторы должны работать только с подмножеством кодировок пользовательских атрибутов (представлением пользовательских атрибутов в метаданных). В таких кодировках разрешается использование только перечисленных ниже типов: System.Type, System.String, System.Char, System.Boolean, System.Byte, System.Int16, System.Int32, System.Int64, System.Single, System.Double и всех типов перечислений, основанных на CLS-совместимом базовом целочисленном типе. |
Метаданные |
|
|
CLS-совместимость |
Все |
Типы, CLS-совместимость которых отличается от CLS-совместимости сборки, в которой они определены, должны быть соответствующим образом отмечены с помощью System.CLSCompliantAttribute. Аналогичным образом должны быть отмечены члены, чья CLS-совместимость отличается от совместимости их типа. Если член или тип отмечен как CLS-несовместимый, необходимо предоставить альтернативный CLS-совместимый элемент. |
Общие |
||
Имена типов |
Компиляторы |
Имя универсального типа должно указывать число объявленных в типе параметров. Имя вложенного универсального типа должно указывать число новых представленных в типе параметров. |
Вложенные типы |
Компиляторы |
У вложенных типов должно быть по крайней мере столько же универсальных параметров, сколько имеется у включающих их типов. Универсальные параметры вложенного типа соответствуют по позиции универсальным параметрам включающего типа. |
Ограничения |
Все |
В универсальном типе должно объявляться достаточно ограничений, чтобы гарантировать, что все ограничения для базового типа или интерфейса удовлетворяются ограничениями универсального типа. |
Типы ограничений |
Все |
Типы, используемые как ограничения для универсальных параметров, должны быть CLS-совместимыми. |
Сигнатуры членов |
Все |
Реализация видимости и доступности членов (включая вложенные типы) в экземплярах универсального типа ограничивается областью конкретного экземпляра, а не объявлением универсального типа. |
Универсальные методы |
Все |
Для каждого абстрактного или виртуального универсального метода должна существовать конкретная (не абстрактная) реализация по умолчанию |
1. Массивы массивов являются CLS-совместимыми. В .NET Framework версии 1.0 компилятор C# ошибочно сообщает, что они не являются таковыми.