Question

Why do I get the compiler warning

Identifier 'Logic.DomainObjectBase._isNew' is not CLS-compliant

for the following code?

public abstract class DomainObjectBase
{
    protected bool _isNew;
}
Was it helpful?

Solution

From the Common Language Specification:

CLS-compliant language compilers must follow the rules of Annex 7 of Technical Report 15 of the Unicode Standard 3.0, which governs the set of characters that can start and be included in identifiers. This standard is available from the Web site of the Unicode Consortium.

If you look this up:

That is, the first character of an identifier can be an uppercase letter, lowercase letter, titlecase letter, modifier letter, other letter, or letter number. The subsequent characters of an identifier can be any of those, plus non-spacing marks, spacing combining marks, decimal numbers, connector punctuations, and formatting codes (such as right-left-mark). Normally the formatting codes should be filtered out before storing or comparing identifiers.

Basically, you can't start an identifier with an underscore - this violates CLS compliant on a visible (public/protected) field.

OTHER TIPS

CLS compliance has to do with interoperability between the different .NET languages. The property is not CLS compliant, because it starts with an underscore and is public (note: protected properties in a public class can be accessed from outside the assembly). Although this will work if the property is accessed from C# it may not if it is accessed from other .NET languages that don't allow underscores at the start of property names, hence it is not CLS-compliant.

You are getting this compiler error, because somewhere in your code you have labelled your assembly as CLS compliant with a line something like this:

[assembly: CLSCompliant(true)]

Visual Studio includes this line in the AssemblyInfo.cs file which can be found under Properties in most projects.

To get around this error you can either:

  1. Rename your property (recommended):

    protected bool isNew;
    
  2. Set your whole assembly to be non CLS compliant:

    [assembly: CLSCompliant(false)]
    
  3. Add an attribute just to your property:

    [CLSCompliant(false)]  
    protected bool _isNew;
    
  4. Change the scope of the property, so that it can not be seen outside the assembly.

    private bool _isNew;
    

The leading underscore concomitant with _isNew being visible (i.e., not private).

The underscore causes the problem. Common practice is that the underscore is reserved for private fields. protected / public members should be properly cased and named.

For example:

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

OR, if you want to use 3.x and get rid of the private field:

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

A CLS-compliant identifier should not start with an underscore.

It's the underscore. See this article.

The leading _ is non-CLS compliant

Microsoft StyleCop will analyze your code, and provide links to the relevent documents explaining why it is not CLS compliant.

Because the name of the data member, _isNew, start's with an underscore.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top