Mono/.NET

I’m quite well versed in C++ (and supporter of Boost,
Loki and libsigc++ – see my
C++/CLI string marshaler), but over time, I started using
.NET more and more until I only resorted to C++ where absolutely required.
That’s because .NET provides a much richer environment (Inversion of Control/
Dependency Injection
containers like Ninject are well established here and unit testing
and test coverage analysis are a breeze whereas most of the C++ world is still
struggling to come to terms with these developments.

In this section, I posted some finished components for Mono and .NET which you
can use freely. If not stated otherwise, all my code is licensed under the
IBM Common Public
License – meaning you can use it in any kind of application, statically link
it and keep your own source code to yourself. The only requirement is that if you
change my code, you make those changes available again (either right away or upon
written request, your choice). I think that’s pretty fair 🙂

Short Primer on Mono/.NET

If you’re using visiting this page because you’re curious about Mono or .NET, here’s a short
explanation about what .NET and Mono are about. It’s a bit like Java, but designed from scratch
with the issues Java ran into over the years kept in mind and a lot of cool sauce added on
top of it.

Compilation Process

Let’s take a look at how programs are compiled by traditional compilers and by a .NET compiler.

Traditional Compiler

Traditional software, written in a programming language like C or C++, is transformed from
source code into machine code by a compiler, producing a so-called binary (usually with file
extensions like .dll, .exe or .so).

This binary can then be run by the end-user as long as his CPU understands the machine code
instructions and his operating system provides the external functions used.

Such binaries are bound to a single platform (= operating system and CPU architecture).
A Windows binary compiled for x64 CPUs won’t work on Linux. At least not
without some kind of emulation software that tries to simulate the platform expected by the
binary. Similarly, it will not work in x86 environments.

.NET Compiler(s)

Source code written in a .NET enabled language is instead compiled to an intermediate format
called CIL (Common Intermediate Language). This language is independent
of any CPU architecture. Only when a CIL binary is executed does it get transformed into
actual machine code by the platform’s .NET runtime.

This means that you can copy a CIL binaries to other computers running a 64 bit OS, Linux,
MacOS or even your mobile phone. Their respective .NET runtime (eg. the
Microsoft .NET Framework or
Mono
will generate suitable machine code in the instant you attempt to launch the program.

So as to not rely on external functions that are operating system specific, .NET defines an
extensive class library called the .NET Framework that interfaces with the underlying
platform and provides .NET programmers with a clean and unified interface. In other words,
a .NET program only interfaces with the .NET Framework and then the platform’s respective
implementation of the .NET Framework does the operations needed by calling into platform
dependent code.

Pros and Cons

Here is a short overview of the advantages and disadvantages of .NET as I see them:

Advantages of .NET

Language Interoperability
Since all .NET-enabled programming languages work through CIL, any .NET language can interface
with any other .NET language.No more wrapper-writing and searching for language bindings.

Portability
Thanks to Mono and other porting efforts such as
DotGnu, software written in pure .NET can
be run on many platforms as-is. In fact, any pure .NET 1.1 oder .NET 2.0 application can
already be run under Linux without modifications.

Reusability
Once compiled, a .NET assembly (the .NET equivalent of a .dll/.so) is
self-describing. Just reference a .NET assembly in your project and you will have access to
all its exposed classes.No more hazzle with headers, DLL import libraries and compiler options anymore.

Drawbacks of .NET

Slower Application Start
Applications written in .NET usually take longer to start than native applications. Doing
actions for the first time will also feel slower than normal because the JIT compiler will
have to compile the code being called first. This can be avoided by pre-compiling an
application when it is installed.

Decompilation
.NET programs can easily be decompiled into code that very closely resembles the original
code minus its comments. Therefore, IP theft and undesirable modification of an executable
to circumvent protection measures or to cheat is easily possible. Using a code obfuscation
tool can make the decompiled code much harder to read but makes updated and patches difficult.

Hickups
Once in a while, the .NET garbage collector will kick in to reclaim unused memory and to
compact used memory into a contiguous block. During this time, an application is essentially
frozen. Garbage collections take just a few milliseconds, but for games this means that the
player will experience a slight jerk in the game. Depending on how carefully a game
is designed, this may happen every few minutes or every two seconds.

Summary

.NET is much more fun to work in because of the well organized .NET Framework, because you can
package your classes in neat assemblies and no longer have to worry about making sure the header
version matches the library, using the right runtime library, static or dynamic binding,
32 bit or 64 bit builds or even which operating system you’re targeting.

Modern language features such as reflection (introspection) and dynamic code generation allow
you to use powerful programming techniques such as unit testing, creating dynamic mocks,
measuring test coverage and managing your dependencies with an inversion of control container.
In C++, only unit testing is marginally supported.

Native code gives you more control and has many more established libraries doing all kinds of
things from image processing to video decoding to physics simulation. Lots of libraries are
being ported to or wrapped in .NET, but until libraries emerge that are written in .NET and for
.NET, these will always be second-class interfaces that lag behind their native counterparts.