Aug 10th 2008 08:59 am
Converting VB to C# while preserving project references and existing solutions
We’ve recently begun converting a tremendous amount of code from VB to C#. Others have much better postings about the pros and cons of chosing VB or C#. The web is littered with religious rants from haughty C# developers (although they are in the minority of .net developers) about which managed language is better.
We chose VB originally because it was easier to develop against, it was a language the team was familiar with, and we didn’t have time to ramp both to .net 2.0 and all the quirks of C#. At the time, there were virtually no features of C# that we felt would make our work more efficient. Over time, however, our team has changed - some of the original developers have moved on and some really smart people with a lot of strong C#/Java experience have joined us. We’ve also had two years to ramp up on .net 2.0 and are now moving on to 3.5 with enthusiasm. Part of the point in moving to 3.5 is to leverage language features only available in C#.
The tool we selected for conversion is C-Sharpener for VB.Net because it converts projects in total and does symbol comparison on the output. Minor quirks of the software include the following:
- in VB, int(5) means an array with upper-bound 5, but in C# int(5) means an array with 5 elements and upper-bound 4)
- a small issue with complex generics- a dictionary whose value was also a generic does not convert properly
- embedded resource references in C# require full names including directory path e.g. to access the embedded resource file name “MyResource.txt” in C#, we would need to call assembly.GetManifestResourceStream( “MyResourceFiles.SomeChildDirectory.MyResource.txt” ) as opposed to the seemingly simpler VB assembly.GetManifestResourceStream( “MyResource.txt” ).
- namespace statements are parsed by period. “Namespace A.B.C” becomes
namespace A
{
namespace B
{
namespace C
{
Once the project is converted, C-Sharpener gives adds the newly created C# project to your solution with the original project name and “_CS” appended to it.
In order to finish the conversion, we need make changes to unmodified versions solution (.sln file) via text editor.
note: C-Sharpener will change the solution when it runs to add the new C# project so be sure to revert the solution after the conversion.
Rather than go through every project’s references and update them to the GUID of the new project we’d like to simply reuse the GUID. This is relatively easy
- Open the source VB project’s vbproj file in a text editor and copy the inner text of the ProjectGuid element.
- Open the csproj file of the newly created project in a text editor.
- update the AssemblyNamespace and RootNamespace elements by removing the extra “_CS”
- Update the <ProjectGuid> element - set the inner text of the element to the inner text of the ProjectGuid from the original vb project.
- open all solutions containing the original vb project in a text editor.
your vb project should be referenced in the file like so:Project(”{ProjectTypeGUID}”) = “MyAssembly”, “..\MyAssembly\MyAssembly.vbproj”, “{MyProjectGUID}”
EndProject - update the path to the newly created cs projectProject(”{ProjectTypeGUID}”) = “MyAssembly”, “..\MyAssemblyInCSharp\MyAssembly.csproj”, “{MyProjectGUID}”
EndProjectnote: you’ll need to update the path to the csproj and make sure the GUID following it (MyProjectGUID) is the same as the one you pasted from the VB project.
- The ProjectTypeGUID indicates to Visual Studio when it tries to compile your solution what kind of project it is - C#, VB, Cobol etc. for example, one of our solutions contains C#, VB, and web deployment projects. It looks like this:Project(”{F184B08F-C81C-45F6-A57F-5ABD9991F28F}”) = “VBProject”, “..\VBProject\VBProject.vbproj”, “{27509F53-2929-459A-8B1E-E03ADA1D8B36}”
EndProjectProject(”{2CFEAB61-6A3B-4EB8-B523-560B4BEEF521}”) = “WebDeploymentProject”, “WebDeploymentProject.wdproj”, “{24F3E583-E313-48D6-92ED-A137AC83BBDB}”
EndProjectProject(”{F184B08F-C81C-45F6-A57F-5ABD9991F28F}”) = “VBProject2″, “..\VBProject2\VBProject2.vbproj”, “{C73B5D28-96D6-4B29-B90D-E0E3788F0692}”
EndProjectProject(”{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}”) = “CSharpProject”, “..\CSharpProject\CSharpProject.csproj”, “{D20CCA67-387E-4B1F-9232-1EEE1359CD9E}”
EndProjectnote how the second GUID in each project is unique. The first GUID is the one you need to change to tell the solution that the project is no longer a VB project but a C# one instead. For your project, update ProjectTypeGUID to the C# guid - FAE04EC0-301F-11D3-BF4B-00C04F79EFBC.
No Comments yet »