Общеязыковая спецификация CLS

97

Как известно, в разных языках программирования одни и те же программные конструкции выражаются своим уникальным, специфическим для конкретного языка образом. Например, в C# конкатенация строк обозначается с помощью знака "плюс" (+), а в VB для этого обычно используется амперсанд (&). Даже в случае выражения в двух отличных языках одной и той же программной идиомы (например, функции, не возвращающей значения), очень высока вероятность того, что с виду синтаксис будет выглядеть очень по-разному.

Как уже показывалось, подобные небольшие вариации в синтаксисе для исполняющей среды .NET являются несущественными благодаря тому, что соответствующие компиляторы (в данном случае — csc.exe и vbc.exe) генерируют схожий набор CIL-инструкций. Однако языки могут еще отличаться и по общему уровню функциональных возможностей. Например, в каком-то из языков .NET может быть или не быть ключевого слова для представления данных без знака, а также поддерживаться или не поддерживаться типы указателей. Из-за всех таких вот возможных вариаций было бы просто замечательно иметь в распоряжении какие-то опорные требования, которым должны были бы отвечать все поддерживающие .NET языки.

CLS (Common Language Specification — общая спецификация для языков программирования) как раз и представляет собой набор правил, которые во всех подробностях описывают минимальный и полный комплект функциональных возможностей, которые должен обязательно поддерживать каждый отдельно взятый .NET-компилятор для того, чтобы генерировать такой программный код, который мог бы обслуживаться CLR и к которому в то же время могли бы единообразным образом получать доступ все языки, ориентированные на платформу .NET. Во многих отношениях CLS может считаться просто подмножеством всех функциональных возможностей, определенных в CTS.

В конечном итоге CLS является своего рода набором правил, которых должны придерживаться создатели компиляторов при желании, чтобы их продукты могли без проблем функционировать в мире .NET. Каждое из этих правил имеет простое название (например, "Правило CLS номер 6") и описывает, каким образом его действие касается тех, кто создает компиляторы, и тех, кто (каким-либо образом) будет взаимодействовать с ними. Самым главным в CLS является правило 1, гласящее, что правила CLS касаются только тех частей типа, которые делаются доступными за пределами сборки, в которой они определены.

Из этого правила можно (и нужно) сделать вывод о том, что все остальные правила в CLS не распространяются на логику, применяемую для построения внутренних рабочих деталей типа .NET. Единственными аспектами типа, которые должны соответствовать CLS, являются сами определения членов (т.е. соглашения об именовании, параметры и возвращаемые типы). В рамках логики реализации члена может применяться любое количество и не согласованных с CLS приемов, поскольку для внешнего мира это не будет играть никакой роли.

Например, возьмем чувствительность к регистру. Язык IL чувствителен к регистру символов. Разработчики, которые пишут на языках, чувствительных к регистру, широко используют гибкость, которую обеспечивает эта зависимость от регистра, при выборе имен переменных. Однако язык Visual Basic 2010 не чувствителен к регистру символов. Спецификация CLS обходит эту проблему указывая, что любой CLS-совместимый код не должен включать никаких пар имен, отличающихся только регистром символов. Таким образом, код Visual Basic 2010 может работать с CLS-совместимым кодом.

Этот пример иллюстрирует, что CLS работает двумя способами:

Изящество этой идеи состоит в том, что ограничения в применении CLS-совместимых средств налагаются только на общедоступные и защищенные члены классов и на общедоступные классы. В пределах приватной реализации классов вы вольны писать любой несовместимый с CLS код, поскольку код из других сборок (единиц управляемого кода) в любом случае не имеет доступа к этой части кода.

Пройди тесты
Лучший чат для C# программистов