Cross Language Interoperability With C# .NET

As you know Microsoft .NET is designed for 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.


Figure1.jpg

Figure 1-1 C# Class Library having a similar function in different cases (upper and lower cases)

In this example, I have declared three functions that differ in the cases 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#.

Now, let's try to consume this C# create .dll in a VB .NET client application.

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

    Dim obj As New ClassLibrary.Class1

    Figure2.jpg

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


But I don't see my C# functions in VB .NET, is there a problem?

Figure 1-2, doesn't show our C# functions Sum, sUm and SUM that we created 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 got the problem, now what is the fix?

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

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

To fix this, we need to make C# assembly CLS complaint, as in:

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

    [assembly:CLSCompliant(true)]

    Figure3.jpg

    Figure 1-3 making the assemble CLS Complaint


Once you have made the change as suggested 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 then make sure you open it via "View" -> "Error List".

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

Figure4.jpg

Figure 1-4 Error List with warnings confirming NON - CLS Complaince

Now, as you will see this code is now complaining about not being CLS Compliant, since we have two functions that differ only in case. So to get rid of these warnings, either we must 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.

Figure5.jpg

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 functions we created. But now you will be able to access all your functions as you have met the CLS Compliance in C#. This is tricky, as you might think that is this real fix? Actually there is no way you can access those case sensitive functions in VB .NET at all, no matter what.

Hence, we have standards to be enforced if needed. This puts a restriction on C# and suggests that you are CLS Compliant 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 e.g. VB .NET.

Figure6.jpg

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