Skip to content

.NET articles

VB.Net to C# conversion  

I recently converted some components on a project from VB.Net to C#, mainly for overloading and better tool support (such as ReSharper). Some of the existing code was generated from my own CodeSmith templates, so a small rewrite to generate C# handled most of that.

VB.Net to C# Converter 1.31

The remaining code, while not extensive in size, is a rather complex affair and the prospect of debugging this code when hand-converted was a little daunting so I decided to give the demo version of VBConversion’s VB.Net to C# Converter 1.31 a spin.

I was rather disappointed it made some rather obvious and stupid mistakes especially when it had converted everything else so well – so much for the 99% accuracy claim. I thought it might just be our project be we adhere to many of Microsoft’s guidelines

Problem 1: Ignores all instance/class variables default assignments and constructors.

Public Class Mine
    Public myObj As MyClass = New MyClass()
    Private myVar As MyEnumeration = MyEnumeration.MyDefault
End Class

Suddenly becomes;

public class Mine {
    public MyClass myObj;
    private MyEnumeration myVar;
}

While the object not being created will soon throw an exception, the defaults for value types is a little harder to track down.

Problem 2: Gives up on Select Case statements after the first case – commenting out the others.

In at least one case it got so confused it commented out substantially more code after the case statement too.

Problem 3: Declares additional unnecessary namespaces including the one for Microsoft.VisualBasic, despite not needing it.

Either we hadn’t used the CDate/CInt/CLng functions or it had converted them)…

Problem 4: All with statements are converted to be variable with1, even when the old with clause was a simple case.

For example:

With myObj
  .doThis()
End With

becomes;

MyClass with1 = myObj;
with1.doThis();

Using both VB.Net and C# together

If you are going to use both in a project you can bring the syntax a little closer in format, here’s a few tips.

  • Don’t use the Visual Basic CInt/CDate/IsNumber etc functions. Use the .NET Framework equivalents such as Int.Parse, Date.Parse etc. which will work in both languages and are normally faster than these legacy functions.
  • Bring the source closer together by;
    • Putting brackets round if conditions in VB.Net
    • Putting quotes round region declarations in C#
    • Putting attributes on separate lines in VB.Net with a _ suffix
    • Dropping the implementation and interface declarations onto a new line in C#
    • Dropping the base(whatever) onto a new line in C# constructors (good idea anyway)
  • Check out the “Differences Between Visual Basic .NET and Visual C# .NET” white paper on MSDN
  • Use VBCommenter to get C# style XML comment documentation.
  • Use Monitor.Enter() instead of VB.Net’s synclock and C#’s lock.
  • Be aware of the differences regarding math! VB.Net defaults to floating point precision and rounding when converting with CInt/CLng etc.. C# normally uses integer division and casting truncates.

[)amien

Firefox for power users, part 2  

Here are a few more useful bits and pieces to improve you browsing experience if you’re a Firefox user.

GreaseMonkey

This great extension provides a framework that allows scripts to run against web pages from your own machine. The upshot of this is…

There are many many more at GreaseMonkeyUserScripts.

CuteMenus

Put icons next to some menu items to bring the UI a bit more in line with Microsoft’s tools.

FlashGot

Download multiple files, images etc. from a single click.

Other browsers

Mac users may want to check out Camino which uses the Gecko rendering engine inside a native Cocoa application. It’s pretty fast and cool although it can’t use any of the Firefox plug-ins. Another alternative browser is OmniWeb which uses the Safari rendering engine but provides many more useful commands, options and facilities than Safari itself.

Microsoft fans will have to wait a little longer until the public Internet Explorer 7 betas turn up. We’ve been promised fixed PNG transparencies and improved CSS handling. In related news Bill Gates has been trying Firefox

Postfix

Just a quck note to praise the free Windows blogging application Zoundry that allows WYSIWYG style editing. I’ve managed to use it to clean up some of the previous postings too. Now if only it had a spell checker and auto-pasted in the clipboard URL when you create a hyper link…

My Visual Studio 2005 Beta 2 DVD’s arrived Saturday free of charge courtesy of Microsoft. I’ve just installed them alongside SQL Developer 2005 and will hopefully be posting some titbits soon. One heads up is to install IIS before VS2005. The VS2005 installer won’t warn you or error however the SQL 2005 installer will tell you it’s a prerequisite if you want Reporting Services. If you install IIS after VS2005 and before SQL 2005 you’ll receive an unidentified error for the Reporting Services installation.

[)amien

My .NET toolkit  

Every developer has his own favourite set of development tools and libraries that he’s come to rely on. Here’s a round-up of some I use or am looking at.

Actively using

  • CodeSmith – Now in version 3 with it’s own IDE this tool lets you write templates that are executed against database structures. The C# ASP.Net style syntax is easy to get to grips with, allowing you to easily generate stored procedures, database scripts, class templates, simple object-relational-mappings, collection classes and the works. Will be less useful when .Net 2.0 arrives with Generics support but until then snap it up. A free version is available.
  • NullableTypes – A shortcoming in .Net 1.1 is the lack of null support for value types outside the SQL Server name space. Until this is addressed in .Net 2.0 then check out this open-source library that does a sterling job. (Disclosure, I’ve contributed to this project)
  • Subversion – A great source control tool, the replacement for the ageing CVS product. Gaining some good support now you can run the server directly or inside Apache. Combine with TortoiseSVN for Explorer shell based integration or AnkhSVN for integration inside the Visual Studio IDE.
  • NUnit – Unit testing is a great way to prevent regressions and NUnit is both simple to learn and fast to use.
  • VisualStyles – I’ve mentioned this before but .Net’s support for XP themes is abysmal with drawing problems all over the place especially when it comes to tab controls. VisualStyles is a free component you just drop on your form that magically fixes everything.

On my radar

  • Trac – Provides wiki, issue tracking and source browsing over the top of a Subversion repository. I installed on my server at the weekend and it looks quite promising although its convoluted installation procedure had far too many dependencies for my liking. Will be testing this on a project I’m working on to see how it goes.
  • PageMethods – Previously called SharpURL’s but now free and without an expiration this provides a way of identifying methods into a web page and the parameters they require.

I’m also on the lookout for a replacement for my object-relational CodeSmith templates I knocked up a while back and have been refining since. While they are functional and incredibly fast I’m now wanting features they don’t provide such as database independence, lazy loading and locking patterns.

[)amien

Lapsed-listeners – Memory leaks in subscriber-publisher scenarios  

I’ve been promising something .NET related for a while… here’s something!

The lapsed-listener problem

There exists a ‘gotcha’ in .NET (and other programming environment) whereby an object has subscribed to another objects published event will not be garbage collected when you expect because the environment itself holds a reference to the subscriber inside the event notification system.

Scenario

Let’s illustrate with an example:

MyBusiness Class

Encapsulates some aspect of business functionality and publishes a Changed event.

MyTreeNode Business Adapter Class

Inherits from TreeNode and takes an instance of MyBusiness in the constructor. The object signs up to the Changed event of the MyBusiness object so that it can always accurately show the correct Icon (via ImageIndex), Text and update any associated child nodes etc.

Now you happily add instances of MyTreeNodeBusinessAdapter class to your TreeView, each with the associated MyBusiness instance it should be reflecting.

The problem now arises in that if the TreeNode is removed from the TreeView with either Nodes.Remove or Nodes.Clear then the garbage collector will not be able dispose of the MyTreeNodeBusinessAdapter objects because the MyBusiness objects hold a reference to them in their event notification queues. Even worse, an inactive TreeView hangs around because the not-yet-disposed TreeNode’s are still pointing to it.

Possible solutions…

.NET Framework 3.0 has a WeakEvent pattern to make things simple!

1. MyTreeNodeBusinessAdapter listens in to TreeView events and un-subscribes when it is removed (Rejected)

TreeNode’s maintain their own internal array of child nodes which they publish under the “Nodes” property which uses the TreeNodeCollection class to just point straight back at itself calling internal methods. None are over-ridable and while they do send the message TVM_DELETEITEM to their own TreeView control it does nothing with them nor does it have methods you could implement in a subclass. (.NET Reflector is great for finding out what’s going on inside the WinForms assembly)

This would also mean every UI control you adapt would need sub-classing to override even if you could hook into the remove events.

2. Weak Events

Xavier Musy’s web log has an interesting C# class called WeakMulticastDelegate that works in a similar way to normal delegates but uses the WeakReference class in .NET to allow referencing an object that can be garbage collected.

This solution also prevents subscribers from subscribing more than once and also from subscribers throwing an exception that stops other subscribers receiving this event (in .Net an exception will break the chain).

Alas it requires that you publish an event by writing Add and Remove methods for your event – not possible directly under VB.Net but possible with the following workaround:

  1. Create a C Sharp Class Library project inside your solution and add the WeakMulticastDelegate code to it (remember to put using System; and using System.Reflection; at the top of the file)
  2. Create a new MyPublisherWorkaround class in the C Sharp project with the private WeakMulticastDelegate… and public event EventHandler… code blocks described in Xavier’s article.
  3. In MyPublisherWorkaround create a method to fire your event (because .NET does not let you raise events defined in a parent class) e.g:
    protected internal void Changed(EventArgs e) {
     if (this.weakEventHandler != null) weakEventHandler.Invoke(new object[] { this, e } );
    }
  4. Add the new CSharp project to your VB.Net project reference and appropriate Imports line at the top of your VB.Net project (obviously).
  5. Change your MyPublisher class to inherit from MyPublisherWorkaround.
  6. Change your MyPublisher class to call the Changed method (or whatever you named it) instead of executing RaiseEvent directly (because of aforementioned restrictions in the .NET framework).

3. Weak Delegates

Greg Schechter on the Microsoft Avalon team has written an article about this very problem and his solution of Weak Delegates.

Our scenario would become:

  1. MyPublisher instance receives request to add instance of MySubscriber to event.
  2. MyPublisher creates new instance of own internal class derived from WeakReference.
  3. This WeakReference instance actually contains the reference to the target object.
  4. The WeakReference instance’s event handler (with the same signature) is added to the event listener.

While this works in VB.Net it has a problem in that the class derived from WeakReference requires all subscribers to either be the same class, derived from a common parent or support a specific interface that defines this event handler.

This defeats much of the point of delegates although it might be possible to rework his code so that WeakReference stores a weak reference to the given event handler and not the object implementing it.

Stepping back

WinForms is focused around the Win32 API itself and not what modern applications require from a UI when developing along Model-View-Controller patterns.

Compound controls such as TreeView and ListView should deal with interfaces such as ITreeNode and IListViewItem and then provide a concrete implementation for backwards compatibility/general use (TreeNode and ListViewItem).

This would solve some issues – check out Skybound’s VisualStyles for a free and easy to use fix for the poor theme support.

Check out the WeakEventManager in .NET 3.5 for an event mechanism that is immunte to this problem.

[)amien