Visual Studio Tip: Three ways to use C# within a VB.NET project

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)
    eh(this, EventArgs.Empty);
}

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) 
End Sub

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

Screenshot showing Solution Explorer for a solution containing both C# and VB.NET projectsOne 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:

using System
[assembly: CLSCompliant(true)]

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.

SET NETCF_DIR="C:\progra~1\Microsoft.NET\SDK\CompactFramework\v2.0\WindowsCE"
 
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.

Sample Application

[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.

4 Responses to “Visual Studio Tip: Three ways to use C# within a VB.NET project”

  1. Tiger.woods says:

    Very nice example and tutorial for us VBer’s wishing to implement external source into our applications.

    The GPS tutorial is especially appreciated by me… kudos and many thanks.

    :>)

    TW,

  2. Christy says:

    Hi, thank you for the article, it was very helpful

    I am still having an issue with the software/hardware though – I don’t know which.

    I am running the program on a symbol mc75 and the program will run – but it gets 0 of 12 satellites – so it does not return any gps information.

    Do you have any idea what I need to do to get the machine to recognize the gps?

    Thanks for any advice – I realize this article is old so I’m hoping someone will see this :-)

  3. Ragnarok says:

    Hey

    I can’t find a CSC.exe anywhere on my computer…

    I am using Visual Studio .NET 2005.

    Thanks

  4. Mitch says:

    Nice tutorial. Good job at telling the newer programmers about multi-file assemblies.

    “The linker is not concerned with what language the individual netmodules were compiled from.”
    Compiled .Net code does not have the language of origin, so the linker doesn’t know what languages they are.

    Also I’m pretty sure using the linker is pointless the vbc.exe and csc.exe have options to compile a multi-file assembley.

    Mitch

Leave a Reply