The .NET framework supports a wide range of languages meaning it is not uncommon to find code examples in a language that you are not familiar or comfortable with. This blog entry discusses some approaches that can be used to include portions of code written in a foreign language within your own application. We will demonstrate the technique by utilising C# code within a VB.NET project.
Technique 1: Code Translation
If you only have a couple of lines of C# to include within your VB.NET application you may like to attempt to manually convert the code into VB.NET so that it can be incorporated directly. If you are having difficulty converting the code (or do not have enough time to learn the specifics of another language) you could try an online code translation service such as the Developer Fusion C# to VB.NET code conversion tool which will attempt to automatically translate the code for you.
For example, given the following C# code:
public event EventHandler Foo;
public void FireFoo()
EventHandler eh = Foo;
if (eh != null)
Developer Fusions’ code translation tool will automatically provide the following VB.NET conversion:
Public Event Foo As EventHandler
Public Sub FireFoo()
Dim eh As EventHandler = Foo
RaiseEvent eh(Me, EventArgs.Empty)
Notice how the code translator is reasonably intelligent, for example it has removed the if statement from the original C# code snippet in favour of the VB.NET specific RaiseEvent statement which internally performs the same check. As with any automated translation utility, your milage may vary with respect to how well the translator copes with your particular code snippet.
Although this technique is useful for small amounts of code it does not lend itself well to converting large amounts of source code, or source code that utilises specialised features of a given language. For this we may like to investigate an alternative technique.
Technique 2: Class Library
One of the many specifications surrounding the .NET environment is one called the Common Language Specification (CLS). This is a subset of CLR features that any language targeting the .NET runtime should support in order to be fully interoperable with other CLS-compliant languages. In other words if you stick to using CLS compliant language features your code should be usable in projects written in a wide range of other languages that also support the Common Language Specification. C# and VB.NET both support the Common Language Specification making it easy for these two languages to interoperate.
If you have a large amount of C# code (such as an entire class) that you would like to include within a VB.NET project you can create a C# class library project and include the source files within it. This allows you to compile the C# source code unmodified and without needing to fully understand how it works. After compilation all you have to do is add a reference to the class library from your VB.NET application as shown in the screenshot to the right. You will then be able to access the C# classes using standard VB.NET syntax.
While writing code how do you know if you are using the subset of language features that are CLS compliant? The easiest way is to add the CLSCompliant attribute to your assembly. If set to true, this will cause the C# or VB.NET compilers to emit warnings whenever they detect that you have used a language feature (or datatype etc) that is non CLS compliant.
For example within a C# class library you might add the following line to the AssemblyInfo.cs file:
Technique 3: Netmodules and assembly linking
I find as a .NET developer it is important to understand the limitations and artificial restrictions imposed by the tools I utilise. You may be surprised to know that Visual Studio does not provide access to every feature of the .NET platform.
One feature not supported by Visual Studio is the ability to compile assemblies that consist of code written in more than one language. For example having an assembly where one class is written in C# while another is written in VB.NET (or even MSIL etc).
If you are willing to drop down to command line compilation it is possible to achieve this. For example given two source files foo.cs and bar.vb we can create an assembly called myassembly.dll by executing the following commands from a Visual Studio command prompt window.
csc /noconfig /nostdlib /r:"%NETCF_DIR%\mscorlib.dll" /t:module foo.cs
vbc /netcf /noconfig /nostdlib /sdkpath:%NETCF_DIR% /t:module bar.vb
link /LTCG /verbose /dll /out:myassembly.dll foo.netmodule bar.netmodule /subsystem:windows
The calls to the C# (csc) and VB.NET (vbc) command line compilers specify the /t:module parameter which causes the compiler to produce a netmodule (foo.netmodule and bar.netmodule respectively). A netmodule can be thought of as being similar to an object (*.obj) file that a native C or C++ developer may be familiar with.
Using the linker (link.exe) enables one or more netmodules to be merged into an assembly, in this case a DLL named myassembly.dll. The linker is not concerned with what language the individual netmodules were compiled from.
[Download multilanguageprojects.zip - 16KB]
The first sample application demonstrates creating a C# class library that can be consumed by a VB.NET winforms application. It takes the textbox cursor location code snippet I wrote in C# and turns it into a C# class library called CSharpClassLibrary.dll. This DLL is then added as a reference to the VB.NET application which makes use of the functionality to highlight the current cursor location within a multiline textbox. Only a minimal amount of C# knowledge was required to make this happen, just enough to wrap the code snippet up into a public class.
This application also demonstrates accessing functionality from an assembly which has classes written in more than one language. Within the MultiLanguageClassLibrary subdirectory you will file a small batch file that demonstrates using the command line compilers to build an assembly that contains individual classes written in C# and VB.NET. As you will see from the VB.NET sample application’s menu item there is no difficulty accessing the functionality of these classes once a reference to the assembly has been added.
[Download gps.zip - 23KB]
This blog entry was spawned by a request for a GPS Intermediate Driver example in VB.NET. The Windows Mobile 5.0 SDK includes an example of how to use this API, but it is written in C#. I have re-coded the GUI part of the GPS Intermediate Driver example into VB.NET and hence produced another example of a C# class library being used from VB.NET. This sample can be downloaded from the link above.