[Journal - Whidbey Migration]

Whidbey Migration

Saturday, December 3, 2005

I have upgraded all projects of the Gregor.NET framework to .NET 2.0, aka Whidbey. Things have gone rather smoothly, and so I have even migrated Gregor.WinShell, a C++ project, from Managed Extensions syntax to the new C++/CLI syntax.

The C++ syntax changes weren't all that difficult to deal with. In the VC++ docs, there is an upgrade check list, and it's a good start. By and large, a global search-and-replace would take care of most items. For this technique, I've found it quite helpful to have consistently formatted code, since some replacements depend on the context:

// old syntax, new syntax:
CShellItem * pItem = new CShellItem();
CShellItem ^ pItem = gcnew CShellItem();

Replacing * and new with ^ and gcnew depends on the data type, so I've included the type name in the search and replace strings. To save time, I first made a list of all reference types used: .NET framework types (including exception types), and types defined in the project itself, and used simple as well as qualified names.

Some of the syntax changes are more tricky, namely, properties, arrays, interface implementations and overrides, NULL vs. nullptr. By the way, there is a compiler warning if the literal 0 or its preprocessed equivalent NULL are being implicitly boxed.

Another minor annoyance lies in the changes to how the language supports overriding System::Object::Finalize and implementing System::IDisposable::Dispose. Finalizers used to be expressed in destructor syntax (like in C#), now a new syntax using the ! operator followed by the class name is used; whereas destructor syntax now indicates you're implementing the Dispose method. I don't think either method is really close to what a C++ destructor is, but then, I've never been a fan of having such syntactical shortcuts for framework-specific tasks. Let's see how various languages support the various cleanup methods - you can see how the C++/CLI finalizer syntax now differs from C# syntax:

WhatVB.NETJ#C#C++/MEC++/CLINative C++
Destructorn/an/an/an/an/a~
FinalizerFinalize()Finalize()~~!n/a
Dispose MethodDispose()Dispose()Dispose()Dispose()~n/a

So, then, all's well that ends well. I'll maintain .NET 1.0/1.1 versions for some time, fixing bugs. New work will be on .NET 2.0 versions only.