Помните, что CLS - это набор правил, которые применяются к сгенерированным сборкам, и предназначен для поддержки взаимодействия между языками. В некотором смысле он определяет наименьшее общее подмножество правил, которым должен следовать тип, чтобы гарантировать его независимость от языка и платформы. Соответствие CLS также применимо только к элементам, которые видны за пределами их определенной сборки.
Следуя некоторым рекомендациям, CLS-совместимый код должен следовать:
- Избегайте использования имен, обычно используемых в качестве ключевых слов в языках программирования.
- Не ожидайте, что пользователи платформы смогут создавать вложенные типы.
- Предположим, что реализации методов с одинаковыми именами и сигнатурами на разных интерфейсах независимы.
Правила определения соответствия CLS:
- Когда сборка не содержит явного атрибута System.CLSCompliantAttribute, она должна быть
предполагается, что он содержит System.CLSCompliantAttribute (false).
- По умолчанию тип наследует атрибут соответствия CLS своего включающего типа (для вложенных типов) или получает уровень соответствия, прикрепленный к его сборке (для типов верхнего уровня).
- По умолчанию другие члены (методы, поля, свойства и события) наследуют CLS-соответствие своего типа.
Теперь, что касается компилятора, (правило 1 CLS), он должен иметь возможность применять правила для соответствия CLS к любой информации, которая будет экспортирована за пределы сборки, и считает, что тип является CLS-совместимым, если все его общедоступные части (те классы, интерфейсы, методы, поля, свойства и события, которые доступны для кода, выполняющегося в другой сборке) либо
- имеют подписи, состоящие только из CLS-совместимых типов, или
- специально помечены как не соответствующие CLS.
По правилам CTS область действия - это просто группа / коллекция имен, и внутри области имя может относиться к нескольким объектам, если они имеют разные виды (методы, поля, вложенные типы, свойства, события) или имеют разные подписи. Именованная сущность имеет свое имя ровно в одной области, поэтому для идентификации этой записи необходимо применять как область, так и имя. Область действия уточняет имя.
Поскольку типы именуются, имена типов также группируются по областям. Чтобы полностью идентифицировать тип, имя типа должно быть квалифицировано областью. Имена типов ограничены сборкой, в которой содержится реализация этого типа.
Для областей, совместимых с CLS, все имена должны отличаться независимо от вида, за исключением случаев, когда имена идентичны и разрешаются путем перегрузки. Другими словами, хотя CTS позволяет одному типу использовать одно и то же имя для поля и метода, CLS этого не делает (правило 5 CLS).
Если сделать еще один шаг вперед, CLS-совместимый тип не должен требовать реализации несовместимых с CLS типов (правило 20 CLS), а также наследовать от другого типа жалобы CLS (правило 23 CLS).
Сборка может зависеть от других сборок, если реализации в области одной сборки ссылаются на ресурсы, находящиеся в области действия или принадлежащие другой сборке.
- Все ссылки на другие сборки разрешаются под контролем текущей области сборки.
- Всегда можно определить, в какой области сборки выполняется конкретная реализация. Все запросы, исходящие из этой области сборки, разрешаются относительно этой области.
В конечном итоге это означает, что для проверки соответствия CLS типа, компилятор должен иметь возможность проверить, что все открытые части этого типа также совместимы с CLS. Это означает, что оно должно гарантировать, что имя является уникальным в пределах области, что оно не зависит от несовместимых с CLS типов для частей своей собственной реализации и что оно наследуется от других типов, также совместимых с CLS. Единственный способ сделать это - изучить все сборки, на которые ссылается тип.
Помните, что этап сборки в Visual Studio - это, по сути, оболочка GUI для выполнения MSBuild, которая в конечном итоге является не чем иным, как скриптовым способом вызова компилятора командной строки C #. Чтобы компилятор мог проверить CLS-соответствие типа, он должен знать и уметь находить все сборки, на которые ссылаются типы (а не проект). Поскольку он вызывается через MSBuild и, в конечном счете, Visual Studio, единственный способ для Visual Studio (MSBuild) сообщить ему об этих сборках - включить их в качестве ссылок.
Очевидно, что поскольку компилятор может выяснить, что он «пропускает» ссылки для проверки соответствия CLS и успешной компиляции, было бы неплохо, если бы он просто включил эти ссылки автоматически от нашего имени. Проблема здесь заключается в определении , какую версию сборки включить и , где эта сборка находится в файловой системе. Вынуждая разработчика предоставлять эту информацию, компилятор помогает гарантировать, что ему предоставлена правильная информация. Это также имеет побочный эффект, заключающийся в том, что все зависимые сборки копируются в папки Debug/bin
или Release/bin
во время сборки, поэтому они находятся в правильном каталоге при запуске приложения после его компиляции.