Use of enum is not CLS-compliant
Asked Answered
M

1

7

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?

Manly answered 13/10, 2015 at 11:2 Comment(10)
Is the class library flagged as CLS-compliant? If not, you'll get that warning.Nadeen
Possible duplicate of Argument type is not CLS-compliant, why?Win
No. But I don't understand why the other 4,000 lines of code in the class aren't giving me CLS-compliance warnings? Only the enums?Manly
@Win - thanks, that article does not explain why an enum is non CLS compliant.Manly
could you please show me the code that you are using to assign value/ access value to the propertyGrappling
Can you mark your C# assembly as CLS-Compliant ([assembly:CLSCompliant(true)]) and then try to build the C# project? Does it give you any extra information about the error?Alfalfa
@Rob, this removes the enum warning, but gives creates other unrelated warnings about passing arrays in constructors. I really want to understand what the CLS-Compliance problem is rather than supressing it.Manly
@RichardMoore Right, I wasn't trying to suppress it, I was hoping for an error/warning which gave a specific reason as to why the enum was not CLS compliant.. Though I'm stumped, now, that the enum itself did not get a warning when compiling the C# project. The only thing I can think of is that the warning is because the entire assembly is not CLS compliant (passing arrays as arguments, etc). Are you able to make a bare-bones C# application with just that enum, and see what happens in the VB project?Alfalfa
@Rob, thanks - good thinking. I made a barebones solution and it was fine!? The enum in the c# class library was accepted happily by the VB.Net Winforms app. So it seems my problem is environmental. I don't have much time to devote to this now, but at least I feel like I've had a bit of a sanity check ;)Manly
It is a stoopid warning, it complains because your C# assembly isn't [CLSCompliant]. Instead of actually checking for compliance on the enum, it just flips the "everything is wrong" flag. Which would be understandable on a class, not so much an enum. Actually checking this has been pointless for the past 10 years, just add <Assembly: CLSCompliant(False)> at the top of the your vb.net source file so it will stop harassing you forever.Colcannon
N
7

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.

Nadeen answered 13/10, 2015 at 12:26 Comment(4)
Why is the enum non compliant, though?Alfalfa
@Alfalfa It's non-compliant because it's defined in an assembly that is non-compliant. I said that in the very first sentence of my reply... ;)Nadeen
Thanks @Matthew, the question is why does the complier only complain about the enums in the non compliant assembly and not the thousands of other classes within it? Is this the compiler just latching onto the nearest thing it can find to complain about?Manly
@RichardMoore Like I say in my answer, you're allowed to USE the other classes, you're just not allowed to return them from a public method or pass them as arguments to a public method in your assembly. Look at my example where it says "This does NOT give a warning".Nadeen

© 2022 - 2024 — McMap. All rights reserved.