2009-07-28 7 views
52

Почему я получаю предупреждение компилятораПочему это имя с подчеркиванием не совместимо с CLS?

идентификатор 'Logic.DomainObjectBase._isNew' не является CLS-совместимый

для следующего кода?

public abstract class DomainObjectBase 
{ 
    protected bool _isNew; 
} 
+23

Вы, вероятно, не должна быть маркировка, не закрытые члены с подчеркиванием в любом случае. Я знаю, что у каждого свой стиль, но другие почти наверняка думают, что поле закрыто вне конвенции. –

+0

@EdS. Какая конвенция? – Pharap

+0

Кажется, что это было соглашение VB за один раз, оно также не соответствует стилю для C++, C#, более подробная информация, чем в этом поле, найденном здесь: https://stackoverflow.com/questions/3136594/naming- условные символы-undccore-in-cc-переменные – MatthewMartin

ответ

77

От Common Language Specification:

CLS-совместимые языковые компиляторы должны следовать правилам, изложенным в приложении 7 Технического отчета 15 стандарта Unicode 3.0, который регламентирует набор символов, которые могут начать и быть включены в идентификаторах , Этот стандарт доступен на веб-сайте Консорциума Unicode.

Если вы look this up:

То есть, первый символ идентификатора может быть прописной буквой, строчной буквой, titlecase письмо, Модификатор письмо, другое письмо, или письмо номер. Последующие символы идентификатора могут быть любыми из них, плюс метки без пробелов, интервалы объединения меток, десятичные числа, пунктуации соединителей и коды форматирования (такие как правая левая метка). Обычно коды форматирования должны быть отфильтрованы перед сохранением или сравнением идентификаторов.

В принципе, вы не можете начинать идентификатор с подчеркивания - это нарушает совместимость с CLS в видимом (общедоступном/защищенном) поле.

+0

http://msdn.microsoft.com/en-us/library/k5645wwb(v=VS.100).aspx – JohnB

+1

Что такое «номер письма»? – Kevin

+2

@Kevin: Все термины в приведенном выше фрагменте относятся к категориям Юникода: «Письмо, прописные буквы», «Письмо, строчные буквы», «Письмо, заголовок», «Письмо, модификатор», «Письмо, другое» и «Число, письмо". Римские цифры - один из примеров номера букв. См. Http://www.fileformat.info/info/unicode/category/Nl/list.htm – Joren

28

Ведущая underscore одновременно с _isNew быть видимыми (то есть, не частный).

+12

+1 Но вам нужно включить тот факт, что член * не является частным *, который вместе с лидирующим подчеркиванием делает имя участника не CLS-совместимым. –

0

Поскольку имя элемента данных, _isNew, начните с символа подчеркивания.

2

Идентификатор, соответствующий CLS, не должен начинаться с символа подчеркивания.

7

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

Например:

public abstract class DomainObjectBase{ 
    private bool _isNew; 
    protected bool IsNew { get { return _isNew; } set { _isNew = value;} } 
} 

ИЛИ, если вы хотите использовать 3.x и избавиться от частного поля:

public abstract class DomainObjectBase{ 
    protected bool IsNew { get; set; } 
} 
+0

Спасибо! Я бы назвал это вторым лучшим ответом, если мог. – MatthewMartin

1

Ведущее _ не является CLS совместимый

Microsoft StyleCop проанализирует ваш код и предоставит ссылки на релевантные документы, объясняющие, почему он не совместим с CLS.

+1

Мне нравится идея StyleCop, но ее правила конфликтуют с правилами FxCop, преобразователем Resharper и преобразователем Visual Studio. – MatthewMartin

+0

StyleCop и FxCop создаются Microsoft (хотя и разными командами), но я считаю, что StyleCop является более поздним и, следовательно, более предпочтительным, если вы хотите использовать стиль кода Microsoft. – Frozenskys

38

CLS compliance имеет отношение к взаимодействию между различными .NET языками. Свойство не соответствует CLS, потому что оно начинается с подчеркивания и является общедоступным (примечание: защищенные свойства в открытом классе могут быть доступны извне сборки).Хотя это будет работать, если доступ к ресурсу из C# невозможен, если он доступен из других языков .NET, которые не позволяют подчеркивать в начале имен свойств, следовательно, это не CLS-совместимый.

Вы получаете эту ошибку компилятора, потому что где-то в вашем коде вы пометили вашу сборку как CLS совместимый с линией что-то вроде этого:

[assembly: CLSCompliant(true)] 

Visual Studio включает в себя эту строку в файле AssemblyInfo.cs, который можно найти в разделе «Свойства» в большинстве проектов.

Чтобы обойти эту ошибку вы можете:

  1. Переименуйте свойство (рекомендуется):

    protected bool isNew; 
    
  2. Установить всю сборку быть не CLS совместимый:

    [assembly: CLSCompliant(false)] 
    
  3. Добавить атрибут прямо к вашей недвижимости:

    [CLSCompliant(false)] 
    protected bool _isNew; 
    
  4. Измените область действия, чтобы ее нельзя было увидеть вне сборки.

    private bool _isNew; 
    
+0

Итак, когда у вас есть общедоступное свойство с защищенной переменной, какое лучшее соглашение? –

+3

Лично мне нравится делать все поля закрытыми. Если мне нужно увеличить масштаб, я бы обернул его в Property Get/Set. –

+0

@MartinBrown: существует много ситуаций, когда класс будет иметь общедоступное свойство, чей сеттер вызывает защищенный метод, который обрабатывает обновления, но где производные типы могут иметь законную необходимость использовать поле напрямую и после публикации обновлений (например, если полученный класс из элемента управления имеет метод изменения как его цвета, так и заголовка, но база не работает, может быть полезным, чтобы производный класс изменял оба поля, а затем вызывал метод обновления один раз). Моя склонность состояла в том, чтобы использовать «Characteristic» и «_characteristic», поскольку и VB.NET, и C# принимают его. Что ты предлагаешь? – supercat

 Смежные вопросы

  • Нет связанных вопросов^_^