.nettypesinteropcls-compliant

CLS vs .NET type compliance: understanding the difference


I'm missing something here. I get that one would use .NET compliant types in public interfaces and methods so that .NET languages can play nicely together (for example, "System.String", not C#'s "string").

If one uses .NET compliant types, then surely all .NET based languages can inter-operate. When and how does CLS compliance factor in?

For example, System.UInt16 is .NET-compliant, not CLR-compliant, and equivalent to "ushort" in C#.


Solution

  • I get that one would use .NET compliant types in public interfaces and methods so that .NET languages can play nicely together (for example, "System.String", not C#'s "string").

    That is actually not an issue. Using C#'s string will result in exactly the same CIL as using System.String.

    When and how does CLS compliance factor in?

    Some languages do not support all types, so CLS compliance is required if you want to support the type system that is going to work cleanly in all languages. This means that ushort (System.UInt16) is not guaranteed to be usable by all .NET languages, so you should avoid exposing it in a public type if you want to be CLS compliant.

    There are other rules you need to follow for CLS compliance, such as not differentiating members merely by case, as some languages are not case sensitive. The type requirements are merely one of many requirements for full CLS compliance.

    The main issue here is that the common .NET languages (such as C#) allow you to use many types, names, and techniques that aren't guaranteed to be available to ALL CLS compliant languages - C# is more flexible than it a language needs to be for CLS compliant. This means that, when you use C# to write code, if you want that code to be usable by all CLS compliant languages, you need to restrict what you expose in public APIs.