1
votes

I have a DLL File which contains a Module named Langs. Inside this Module I have a class called AvailableLanguage, the class definition is as follow:

Public Class AvailableLanguage
    Implements IEquatable(Of AvailableLanguage)

    Private _langID As Integer
    Private _langName As String

    Public ReadOnly Property LanguageID As Integer
        Get
            Return _langID
        End Get
    End Property

    Public ReadOnly Property LanguageName As String
        Get
            Return _langName
        End Get
    End Property

    Public Sub New(ID As Integer, Name As String)
        _langID = ID
        _langName = Name
    End Sub

    Public Overrides Function Equals(obj As Object) As Boolean
        If obj Is Nothing Then Return False
        Dim L1 As AvailableLanguage = CType(obj, AvailableLanguage)
        Return Me.Equals1(L1)
    End Function

    Public Function Equals1(other As AvailableLanguage) As Boolean Implements IEquatable(Of AvailableLanguage).Equals
        Return Me.LanguageID = other.LanguageID
    End Function

    Public Shared Operator =(Lang1 As AvailableLanguage, Lang2 As AvailableLanguage)
        Return Lang1.Equals1(Lang2)
    End Operator

    Public Shared Operator <>(Lang1 As AvailableLanguage, Lang2 As AvailableLanguage)
        Return Not Lang1.Equals1(Lang2)
    End Operator

    Public Overrides Function ToString() As String
        Return _langName
    End Function
End Class

I use this class in another DLL containing a Windows Form. For now my Windows Form is quite empty:

Public Class LanguageSettings
    Public Property AvailableLanguages As List(Of Langs.AvailableLanguage)
End Class

But right there, Visual Studio 2012 Express throws me a warning, saying:

Type 'AvailableLanguage' is not CLS Compliant.

From MSDN, I understand that some types make a class or function not CLS Compliant, however I'm not using any of those, this is just an Integer and a String.

I can hide the warning if I had the CLS Compliant Attribute to True:

<CLSCompliant(True)>

However I don't understand why thsi class is not CLS Compliant.

Obviously it's not because of the Property types. So left are:

  • The IEquatable(Of T) Interface
  • The = and <> operators

Which one is it ?

EDIT

I removed all the function and interfaces and got the exact same result. I'm just creating an object with a few readonly properties (types Integer and String) and the form class tells me that AvailableLanguage is not CLS Compliant.

If I add a private field of type AvailableLanguage in my form Class, no warning is displayed:

Public Class LanguageSettings
    Private L As Langs.AvailableLanguage 'No warning
    Public Property AvailableLanguages As List(Of Langs.AvailableLanguage) 'Warning
End Class

I honnestly would like to understand what's going on and how this CLS Compliant thing works.

1
"Which one is it ?" - That sounds like something you can answer for yourself, by removing members one at a time until the warning goes away. I note that you're overriding Equals but not GetHashCode, which may be relevant.Jon Skeet
@JonSkeet Actually I might change the question title, it's neither of them. I removed everything but the properties and still have the same issue.Martin Verjans
Providing a minimal reproducible example would certainly help.Jon Skeet

1 Answers

1
votes

Read the documentation for ClsCompliant attribute again - it's not a lie/hiding kind of attribute:

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.

If it's not applied to the type, or at least to the assembly, then the assumption is non-compliance. I believe the compiler will error/warn if you actually try to apply it to something non-compliant.