Lately, I’ve been doing development of a Windows 8 Metro application using C++ only (yes, that’s right, no C#) for a client. The reasons for that are mainly an existing C++ code base and a good C++ acquaintance that the team in question has.
I’ve been using the new C++/CX extensions that make it easier to work with the Windows Runtime (WinRT); easier with respect to the Windows Runtime Library (WRL) that uses standard C++ with a bunch of helpers (such as ComPtr<T> as a smart pointer for a COM/WinRT interface).
Even with C++/CX, the amount (verbosity) and complexity of of code that’s needed is higher than in C#. Here are some highlighted differences:
Defining regular property
A simple thing, isn’t it? First, let’s check out C#:
We can do this by wrapping a private field, but essentially it’s the same as a regular .NET property.
Here’s the equivalent code in C++/CX. First, the header file:
The set and/or get must be specified fully. Now the implementation:
The code assumes that a private field named _value is defined in the class header (no automatic properties in C++).
Registering for an event
C#: use regular event syntax, with or without a lambda expression. Examples:
In C++, both approaches are possible, but here’s the big difference:
The real issue here is that the compiler insists that even in the case of a lambda function (which is of a known type to the compiler), the entire signature be specified exactly and the delegate object created. Redundancies everywhere.
Defining dependency properties
When creating templated or user controls, there is a need to define dependency properties. The definition in C# is exactly the same as it’s defined in WPF or Silverlight: a public static field and a get/set wrapper. Here’s a Text property added to some user control:
What about C++? Not much fun. First, the header file:
That sets the property wrappers, the private static field and the public static property wrapping that field. Why don’t we make the field public and be done with it? That’s not allowed for a WinRT type – it can only expose methods (or properties which eventually are methods as well), but not fields (everything is part of a vtable based interface).
Now for the implementation file (statics must be initialized):
ChatElement is the example user control type. The TypeName structure is projected to C# as a regular System.Type, but not in C++.
All this for just one dependency property!
C# excels here, with the await keyword used for every IAsyncOperation<T> type interface (and similar interfaces):
In C++, the regular way is handling the Completed event with a lambda function and then moving on from there. The problem is that we need to specify captured variables, and with nested asynchronous operations this gets tedious (see event registration above):
Amazingly enough, this is equivalent to the previous C# code snippet…
Some operations don’t return on the same thread, so the UI dispatcher has to be invoked; this is pretty bad. Fortunately, we can improve things by using the new Concurrency::task<> class like so:
This is certainly better, but it’s not an integral part of C++/CX, but rather a C++ class that “happens” to help. Even with this construct, it’s still pretty far from the C# version.
C++/CX is a step in the right direction, but it’s not yet (in my humble opinion) a viable alternative to C# for a medium or large metro application. C++/CX is certainly required for writing WinRT components, because it’s the only language that guarantees no CLR involvement. Writing a C# component is problematic in the general case, as a C++ client would have to incur the overhead of the CLR which is a primary reason to use C++ in the first place.
With the right improvements – basically less verbosity and redundancies – C++ can become an easy to use language for metro apps. Coupled with its immediate access to almost any C++ library (and DirectX!) makes it the most powerful language in the WinRT world.