Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of enum is not CLS-compliant

I have the following code in a c# class library...

public static class foo
{
    public enum bar
    {
        bsNone = -1,
        bsSolid = 0,
        bsDash = 1  
    }
}

And in a VB.Net Winforms application I reference the enum as the return type of a property:

Private _LeftBorderStyle As foo.bar
Public Property LeftBorderStyle() As foo.bar
    Get
        Return _LeftBorderStyle
    End Get
    Set(ByVal value As foo.bar)            
        _LeftBorderStyle = value
    End Set
End Property

When I build the VB.Net project I get the following warning:

Return type of function 'LeftBorderStyle' is not CLS-compliant.

Can you tell me why the enum is non-CLS compliant?

like image 801
Richard Moore Avatar asked Oct 13 '15 11:10

Richard Moore


Video Answer


1 Answers

This is happening because you are publicly exposing from an assembly marked as CLS-Compliant a type that is from an assembly that is not CLS-Compliant.

Note that you are allowed to consume a type that is not CLS-Compliant in a CLS-Compliant assembly; but you are not allowed to expose such a type.

For example, assume you have this class in a non-CLS-Compliant assembly:

namespace NonCLSCompliantAssembly
{
    public class Class1
    {
        public enum MyEnum
        {
            Red,
            Green,
            Blue
        }
    }
}

Now assume you have the following class in a CLS-Compliant assembly that references the non-CLS-Compliant assembly:

namespace CLSCompliantAssembly
{
    public class Class1
    {
        // This does NOT give a warning.

        public int MyTest1()
        {
            return (int) NonCLSCompliantAssembly.Class1.MyEnum.Red;
        }

        // This DOES give a warning.

        public NonCLSCompliantAssembly.Class1.MyEnum MyTest2()
        {
            return NonCLSCompliantAssembly.Class1.MyEnum.Red;
        }
    }
}

The compiler will NOT warn you about MyTest1()'s use of the type MyEnum from a non-Compliant assembly, because it is only being used internally.

But it WILL warn you about exposing it as the public return type of MyTest2().

If you make the non-CLS-Compliant assembly compliant by adding [assembly: CLSCompliant(true)] to AssemblyInfo.cs, then the code will all compile without a warning.

To reiterate: If you use a type defined in a non-compliant assembly, that type is automatically non-compliant, even if it is just something basic like an enum.

From the Microsoft documentation for CLSCompliantAttribute:

If no CLSCompliantAttribute is applied to a program element, then by default:

  • The assembly is not CLS-compliant.

  • The type is CLS-compliant only if its enclosing type or assembly is CLS-compliant.

  • The member of a type is CLS-compliant only if the type is CLS-compliant.

like image 61
Matthew Watson Avatar answered Sep 28 '22 19:09

Matthew Watson