Understanding Cross Language Interoperability With C# .NET


As you know Microsoft .NET is designed with cross-language interoperability. In other words two .NET compliant languages can interoperate with each other. Which simply means a function in VB .NET can be called by C# and vice-versa.

Let's understand this practically and consider a scenario where a C# class library (.dll) is being used by the VB .NET client (.exe).

Create a C# Class Library project

  1. If not already, promote the Class1 to be public.
  2. Create functions as shown in Figure 1-1 below.
  3. Compile the code, to have a .dll successfully produced in the bin\debug folder.

    Figure 1-1 C# Class Library having similar function in different casing

In this example, I have declared three functions that differ in the casing of the letters used to form the name of function (in other words Sum, sUm and SUM). This is totally possible considering we are working with a case sensitive language of choice, C#.

The following describes the consumtion of that in C#. Create .dll in a VB .NET client application as in the following:

  1. Create a VB .NET Console Application.
  2. Add a reference to ClassLibrary.dll that we created in C#
  3. Add an Imports ClassLibrary.Class1 in the VB .NET code file, as shown in the image below
  4. Create an object of the class library as in the following:

    Dim obj As New ClassLibrary.Class1

    Figure 1-2 VB .NET Console application consuming C# Class library

But I don't see my C# functions in VB .NET.

Figure 1-2 doesn't show our C# functions Sum, sUm and SUM that we created as shown in Figure 1-1. There is a problem and that is a genuine issue. Let's understand this.

If you observe the C# is fully capable of declaring functions that differ only by case, VB .NET is completely incapable of recognizing this case difference (due to its case in-sensitivity). This is the reason that we don't see those C# functions in VB .NET.

I understand the problem, now what is the fix?

The fix for this problem is to follow the Common Language Specification (CLS). The CLS needs to be followed by another language that won't be able to recognize and understand.

For example, class members that differ in case and UInt and so on are not considered CLS Compliant. Let's enforce the CLS compliance in C#, so the case sensitive nature can't be misused to break inter-operability with clients like VB .NET or similar .NET complaint language(s).

Understanding CLS Compliance

To fully interact with other objects written in any language, objects must expose to callers only those features that are common to all languages. This common set of features is defined by the Common Language Specification (CLS), that is a set of rules that apply to generated assemblies.

Making C# assembly CLS Complaint

  1. Go to Cthe # Class Library project
  2. Open Class1.cs
  3. On the top of namespace ClassLibrary, add the statement:


    Figure 1-3 making the assemble CLSComplaint

Once you have made the change as suggested just above and in Figure 1-3 build the class library and you should observe the Warnings list in the Error List window. If the Error List window doesn't show up be sure you open it via View -> Error List.

When you open the Error List, you will see the warnings as shown in Figure 1-4 below.

Figure 1-4 Error List with warnings confirming NON - CLSComplaince

Now, as you can see this code is complaining about not being CLSCompliant, since we have two functions that differ only in case. So to eliminate these warnings, either we need to change the function names or remove these from the class library.

Let's try changing the name for these two functions to Sum2 and sUm3 as shown in Figure 1-5 below.

Figure 1-5 renamed functions to confirm the CLSComplaince

Let's re-test this with VB .NET

We already have VB .NET code, as shown in Figure 1-2 above where we didn't have access to the earlier functions we created that differ in case. But now you will be able to access all the functions since we have met the CLSCompliance in C#. This is tricky, as you might think, is this a real fix? Actually there is no way you can access those case sensitive functions in VB .NET at all.

Hence, we have standards/rules to be enforced if needed. This enforces a restriction on C# and suggests that your code uses CLSCompliant(true) and so be careful when declaring class members that differ only in case or try to use something that is only used by C# for example UInt16 that is not used by many other languages for example VB .NET.

Figure 1-6 VB .NET showing access to C# functions after CLSComplaince of C# assembly

Video Tutorial