Почему C# включает конструкции программирования, не совместимые с CLS?

Кажется странным, что флагманский язык .NET будет включать в себя конструкции программирования, не совместимые с CLS. Почему так?

пример (из здесь):два или более публичных / защищенных / защищенных внутренних членов, определенных только с разницей в случае

public int intA = 0;
public int INTA = 2; 

или

public int x = 0;

public void X()
{
} 

7 ответов


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

они в конечном счете там, чтобы дать вам свободу использовать их при необходимости. Чувствительность к регистру, о которой я мог бы стать менее религиозным-несмотря на удобство иметь поля и свойства отличаются только кейс, я думаю, что смогу жить счастливо, если меня заставят использовать другое имя! Особенно теперь, когда мы автоматически реализовали свойства...

это похоже на то, как он позволяет использовать unsafe - разница здесь в том, что несколько целых чисел без знака не будут дестабилизировать всю среду выполнения, поэтому им не нужны такие сильные Молли-охранники.

можно добавить:

[assembly: CLSCompliant(true)]

Если хотите, и компилятор скажет вам, когда вы его получите неправильный.

и наконец: большинство код (по объему) не используется в качестве компонента. Он написан, чтобы выполнить работу, и, возможно, потребляется другим кодом в доме. Это в основном библиотеки писателей / поставщиков, которые должны беспокоиться о таких вещах, как соответствие CLS. То есть (по численности) меньшинство.


Это не так, как CLS соответствие работает. Это то, что код бремя. C# не ограничивает себя строгой податливостью, что сделало бы его языком с плохой выразительностью. Перетаскивание всех языков .NET вниз до самого низкого общего знаменателя быстро убило бы платформу как жизнеспособную среду программирования.

Это до вас, чтобы убедиться, что публично видимые типы в вашей сборке соответствуют требованиям CLS. Убеждающийся что члены класса не отличаются только регистром очень просто сделать. Пусть компилятор поможет вам с помощью атрибута [assembly:CLSCompliant(true)], и компилятор предупредит вас, когда вы поскользнулись.


см.http://msdn.microsoft.com/en-us/library/bhc3fa7f.aspx.

CLS-это спецификация, которую можно выбрать. Цитата сверху:

при разработке собственных CLS-совместимых компонентов полезно использовать CLS-совместимый инструмент. Писать CLS-совместимые компоненты без этой поддержки сложнее, поскольку в противном случае у вас может не быть доступа ко всем функциям CLS, которые вы хотите использовать.

некоторые CLS-совместимые языковые компиляторы, такие как компиляторы C# или Visual Basic позволяют указать, что код должен быть CLS-совместимым. Эти компиляторы могут проверять соответствие CLS и сообщать, когда код использует функции, не поддерживаемые CLS. Компиляторы C# и Visual Basic позволяют пометить программный элемент как CLS-совместимый, что приведет к созданию компилятором ошибки времени компиляции, если код не CLS-совместимый. Например, следующий код создает компилятор предупреждающий.


пример кода сверху ссылка:

using System;

// Assembly marked as compliant.
[assembly: CLSCompliant(true)]

// Class marked as compliant.
[CLSCompliant(true)]
public class MyCompliantClass {
   // ChangeValue exposes UInt32, which is not in CLS.
   // A compile-time warning results.
   public void ChangeValue(UInt32 value){ }

   public static void Main( ) {
   int i = 2;
   Console.WriteLine(i);
   }
}

этот код генерирует следующее предупреждение C#:

копировать предупреждение CS3001: тип аргумента 'uint' не соответствует CLS


мои два цента о соответствии CLS

языки .net-это все эволюции языков, которые существовали во время его создания. Языки были созданы таким образом, чтобы вы могли легко конвертировать базовые проекты в проекты .Net без особых усилий по разработке. Из-за огромных различий между языками необходимо было какое-то соглашение, чтобы языки разговаривали друг с другом. Возьмите примеры ниже:

VB.Net это язык, производный от более раннего языка VB6. Предполагается, что он очень похож по стилю на VB6 и как таковой занимает много конвенций VB6. Поскольку VB6 должен был быть простым в освоении / использовании не разработчиками, он имеет определенные характеристики,которые делают его более идиотским. Динамическая типизация, нечувствительность к регистру-две из этих вещей.

C#.Net/C ++ .Net являются производными от более дружественного программисту C++. Поскольку они являются эволюцией этого языка, в нем есть вещи, которые C++ позволит вам это сделать. Чувствительность случая, статический печатать etc.

теперь, столкнувшись с двумя разными языками, которые они хотели сделать совместимыми, Microsoft сделала единственную разумную вещь. Они сделали ограничения на то, как два языка могут взаимодействовать друг с другом через использование в основном программного контракта. Этот код можно использовать только таким образом из-за различий в языках.

например, возьмите VB.Net код вызова кода C# Если бы код C# имел две функции, которые отличались только в случае, X () vs x (), VB.net никогда не сможет правильно вызвать этот код, поскольку он нечувствителен к регистру. Соблюдение CLS должно сделать это незаконным. Если вы посмотрите на другие правила, они в основном делают то же самое для других языковых функций между разными языками.


Я бы предположил, что нечувствительность к регистру была включена только в соответствие CLS, чтобы VB.NET может быть CLS-совместимым. Насколько я понимаю, нет никаких проблем, если конкретная языковая конструкция не совместима с CLS, если вы не используете ее таким образом, чтобы несовместимые peices были доступны в общедоступном API вашего кода.

подсказка от Microsoft, похоже, заключается в том, что соответствие CLS важно только в коде, к которому вы обращаетесь с разных языков (например, ссылка на сборку C# из a VB.NET проект).


Я думаю, что Microsoft хочет дать разработчикам свободу. Никаких ограничений, если нет необходимости. C# не ограничен CLS, потому что не всем нужна совместимость с VB.


Если бы существовало всеобщее согласие относительно того, какие функции должны быть включены в язык программирования, миру был бы нужен только один язык программирования (который включал бы именно те функции, которые все согласились должны быть там). Конечно, на самом деле некоторые люди будут рассматривать как важные особенности, которые другие не заботятся (или даже находят неприятными). Стандарт CLS по существу делает три вещи:

  1. Он говорит, что некоторые функции настолько важны, что любой язык, который не включает их, следует считать неадекватным для программирования .net общего назначения.
  2. в нем говорится, что программисты, чьи библиотеки не требуют каких-либо функций, кроме перечисленных, должны ожидать, что их библиотеки будут использоваться программистами, использующими любой язык, подходящий для программирования общего назначения .net.
  3. он сообщает программистам, что если части их библиотек потребуют использования функций, языки которых не требуются для поддержка, эти части не могут быть использованы в языках, которые подходят для программирования .net, но не включают необходимые функции.

когда языки любят vb.net или C# позволяет создавать не совместимое с CLS Программирование, что означает, что Microsoft решила, что определенные функции достаточно полезны, чтобы оправдать включение в эти языки, но не настолько замечательны или неконтролируемы, чтобы оправдать обязательное включение всех языков.