.NET Framework Bookmark and Share   
 index > Common Language Runtime > CLS compliant
 

CLS compliant

Lately I've received the "Type of parameter 'e' is not CLS-compliant" a lot. I really can't figure out what it is that makes some of my classes non-compliant, an example:

Code Snippet

Imports System.Windows.Forms

''' <summary>

''' Event arguments for the Complete event.

''' </summary>

Public Class CompleteEventArgs

Inherits EventArgs

''' <summary>

''' Creates a new instance.

''' <summary>

''' <param name="result">The result of the completed task.</param>

Public Sub New(ByVal result As DialogResult)

Me.mDialogResult = result

End Sub

#Region "DialogResult"

Private mDialogResult As DialogResult

''' <summary>

''' The result of the task.

''' </summary>

Public ReadOnly Property DialogResult() As DialogResult

<System.Diagnostics.DebuggerStepThrough()> _

Get

Return Me.mDialogResult

End Get

End Property

#End Region 'DialogResult"

End Class

When using the above class in an event handler for the event the compiler will show a warning that the type of the parameter e is not CLS-compliant, anybody knows why?

Code Snippet

Public Delegate Sub CompleteEventHandler(ByVal sender As Object, ByVal e As CompleteEventArgs)

Cheers,

Patrik

Patrik Hägne

Is the CompleteEventArgs class located in an assembly that is CLS-compliant by default? i.e.: Does the project have the following assembly-level attribute:

Code Snippet

<Assembly: CLSCompliant(True)>

Nicole Calinoiu

Is the CompleteEventArgs class located in an assembly that is CLS-compliant by default? i.e.: Does the project have the following assembly-level attribute:

Code Snippet

<Assembly: CLSCompliant(True)>

Nicole Calinoiu
Actually, no, you're right, the assembly wasn't marked as CLS-compliant, so I feel a bitsilly. I actually thought of this onmy way home from work yesterday. What puzzles me though is that the use of other types from the same assembly does not generate this warning.
Patrik Hägne

You will only get this error if you use non-CLS-compliant types in public parts of your component. So the line you've quoted in this thread causes the error because it's marked as public.

It's absolutely fine to use non-CLS-compliant types privately. So it's OK to use them as local variables inside a method, because a method's local variables are not publically visible. Also, it's OK to use them on internal or private members. That's why you might not have seen this error before even though you've used non-CLS types before.

CLS-compliance is all about what the public face of your component looks like.

IanG
Yes ofcourse I understand that it only affects public parts. But what I mean is that I use other parts of the assembly the was not marked as CLS-compliant from other assemblies, I couldn't use them if they weren't public right (well, I could use internal/friend parts to if I did allow it).
Patrik Hägne

If an assembly is marked as non-CLS compliant, all it's saying is "Some parts of this assembly are not CLS compliant." It doesn't mean the whole thing is non-CLS compliant.

CLS compliance rules are based on which types you use, not which assemblies you use. So if you use a type from an external assembly in your public interface, it's not relevant whether or not that external assembly is CLS-compliant. It only matters that the types from that assembly that you're exposing in your public API are CLS-compliant.

IanG

I'm not sure I'm getting what you mean. The assembly wasn't marked as non-CLS-compliant, at least not explicitly. The this is that it wasn't marked as CLS-compliant, does that imply that it's non-CLS-compliant? I've used different public types from the assembly not marked as CLS-compliant from other assemblies, none of these types were marked as either compliant or non-compliant but only the use of the aforementioned type generated the compiler warning and I still don't understand why.

Patrik Hägne
Marking an assembly with CLSCompliantAttribute (true or false)has no directeffect on the actual CLS-compliance of the contents of the assembly. The only consequence is at compile-time, where the compiler will generate errors if a code element that has been marked as CLS-compliant (via an attribute at the assembly, type, or member level) is in fact not CLS-compliant. In other words, it's quite feasilble for code that has not been marked with CLSCompliant(false) to still be CLS-compliant, although the inverse should not be true (but may be if the compiler fails to flag certain non-compliance issues).
Nicole Calinoiu
Ofcourse, that's pretty obvious. Not sure what it has to do with my question though.
Patrik Hägne

It was in response to what you wrote here:

"What puzzles me though is that the use of other types from the same assembly does not generate this warning. "

My second post and Nicole's second post both explain why you get the warning with some types from that assembly but not with others. That's what it has to do with your question.

(My first post turned out to be irrelevant by the way.The reason I posted that was that you hadn't supplied enough information for anyone to deduce what it was you were missing, soI had to guess. My guess was wrong.)

You seemed to be under the impression that if an assembly is marked as non-CLS-compliant, that this meant any types it exposed were by definition non-CLS-compliant. You might not actually have thought that, but what you wrote made it seem like that was what you thought.

So I explained the thing you seemed to be missing. You said you hadn't understood , so Nicole patiently explained to you how CLS compliance works. You then said you "Ofcourse, that's pretty obvious" and then went on to demonstrate that you hadn't actually understood what she wrote by saying "Not sure what it has to do with my question though."

Just to sum up, as far as I can tell, you've now been given all the information you require to understand what's happening, but for some reason you're rejecting it.

To sum up the information required to explain what you're seeing:

  1. Whether a particular type is CLS-compliant has absolutely nothing to do with whether it or the assembly that contains it is marked as CLSCompliant(true).
  2. The warning you're seeing is what you get if you mark an assembly or type as CLSCompliant(true) when it is not in fact CLS compliant.

The second point seems to explain why you saw the warning: your assembly was marked as CLS-compliant, and the compiler notice that one of the types it used in a public member wasn't CLS-compliant. In other words, the warning was simply the compiler keeping you honest. The presence of CLSCompliant(true) on your assembly was interpretted as you saying "The public types in this assembly are CLS compliant." The warning was the compiler saying "No they're not".

The first point explains why your use of other types from the same assembly does not generate this warning. The C# compiler simply doesn't care whether the assemblies you are using are marked as CLS-compliant or not. The attribute

IanG

Thank's for the reply, I didn't mean to sound arrogant, or, maybe I did, but if so I was wrong to be. Probably I'm just frustrated that there seems to be a language barrier for me since I'm from sweden and english is not my native language.

Your long and informative answer explains a lot, nothing of it is new to me though, or at least I didn't think it was. How you are describing that cls-compliance works is exactly how I thought it worked before I posted. Then when I was asked if my assembly was decorated with the CLSCompliantAttribute I went and checked and saw that it wasn't. Actually it isn't "my" assembly since it belongs to my employer and there have been many developers working on it over time. When I applied the attribute to the assembly this fixed the problem and I don't get the warning anymore, therefore I re-thought how cls-compliance worked and thought, well maybe it's just based on if it has been marked cls-compliant or not. This is ofcourse where I was wrong as you've now pointed out. But then I'm really back to the original question, why was the warning raised for the public type I showed code examples for? There are no public members starting with an underscore, no members differing only by case (wouldn't even be possible in VB), no use of other non-cls-compliant types (if System.Windows.Forms.DialogResult is cls-compliant, wich I assume it is) and no overloaded operators. So is there any other rule for cls-compliant the type I supplied in my code example breaks?

1. Is it because the assembly was not marked as cls-compliant, but the type still was compliant, just considered non-compliant?

2. Is it because the type break any (to me not known) rule for cls-compliance?

If the first answer is correct then I still don't understand why the use of other public types from the assembly didn't generate any warnings because they (following the same logic) should be considered non-compliant as long as they're not explicitly marked as compliant.

If the second answer is correct then I still don't know what rule the class is in violation of.

The first answer seems to be the correct one to me, let's say assembly A is not marked as cls-compliant and exposes two types A1 and A2. In assembly B, which is marked as cls-compliant I make use of they type A.A1, now this should generate a warning right, because I've marked my assembly B as cls-compliant therefore instructing the compiler to enforce compliance and A.A1 is not considered compliant since it's not marked as compliant. But now I make use of the type A.A2 from my B-assembly, this should generate the same warning right, but in my case it didn't, wich I can't explain.

Also the msdn-documentation for the CLSCompliantAttribute states the following: "The current Microsoft Visual Basic compiler intentionally does not generate a CLS-compliance warning, however, a future release of the compiler will issue that warning" which seems a bit strange to me since this is in all the versions of the documenation (1.1, 2.0 and 3.0), I guess that's just wrong in the documentation though.

So, maybe you've already given me the answer to why I received a warning in one case but not in an other, but if you have I still haven't understood and then I guess I'm just plain stupid. Actually I'm probably just plain stupid anyway, but that's a whole different story ;-) I do very much appreciate the help so please don't let my sarcasms get to you...

Thank's in advance,
Patrik

Patrik Hägne

As far as I can tell, the code you posted doesn't in fact cause the warning you describe. I pasted it into an example that declares the type you show, declares a delegate type as you show, defines a class that raises an event with that delegate type, and defines a class that handles that event:

Code Snippet

Imports System.Windows.Forms

''' <summary>

''' Event arguments for the Complete event.

''' </summary>

Public Class CompleteEventArgs

Inherits EventArgs

''' <summary>

''' Creates a new instance.

''' </summary>

''' <param name="result">The result of the completed task.</param>

Public Sub New(ByVal result As DialogResult)

Me.mDialogResult = result

End Sub

#Region "DialogResult"

Private mDialogResult As DialogResult

''' <summary>

''' The result of the task.

''' </summary>

Public ReadOnly Property DialogResult() As DialogResult

<System.Diagnostics.DebuggerStepThrough()> _

Get

Return Me.mDialogResult

End Get

End Property

#End Region 'DialogResult"

Public Delegate Sub CompleteEventHandler(ByVal sender As Object, ByVal e As CompleteEventArgs)

Public Class Source

Public Event MyEvent As CompleteEventHandler

End Class

Public Class Handler

Dim WithEvents src As Source

Private Sub src_MyEvent(ByVal sender As Object, ByVal e As CompleteEventArgs) Handles src.MyEvent

Debug.WriteLine("Foo")

End Sub

End Class

End Class

This doesn't produce any warnings.

Since you said the problematic type was in a separateassembly, I put that in its own library. Still no warning.

I then tried marking the library with CLSCompliant(False) to see if that would have any effect. Still no warning.

I tried moving the CompleteEventHandler delegate type over to the library. Still no warning.

And finally, I tried moving the event source over the the library. Still no warning.

So I've been unable to getthe code you posted to cause a CLS compliance warning. So theorizing over why it causes one isn't going to be a productive activity. Could you post a complete example that generates the warning?

IanG

Ian, thank's a lot for your efforts, I can however not post a complete example since I can not re produce it myself outside the context of the actual production projects, wich I can not for obvious reasons post here.

To me the problem is solved, since tagging the typ with the CLSCompliantAttribute did help, however I'm still not sure why I got the warning in the first place, especially since the msdn-documentation states that no warnings should be issued by the VB-compiler.

Cheers, Patrik

Patrik Hägne
Dude! Someone probably simply turned on Code Analysis on your project. You can write classes with public stuff all day long with no complaints by the compiler until you turn on Code Analysis, then suddenly you have all sorts of things you should and shouldn't be doing crop up.
-L1
the Larker1

You can use google to search for other answers

Custom Search

More Threads

• Appdomain::Unload does not unload an assembly
• Threading - block a method call but continue execution
• Enumerating the processes associated with a service.
• GetProcessByName
• CryptDeriveKey give different results WinXP and Win2K
• XMLDocument.Load Method (String) and passing in an unqualified file name
• WaitHandle synchronization issues, or how to avoid deadlocks ?
• what is loader
• Threads creating handle leak?
• Dispose. Is Bitmap managed resoure ?