I first bumped into Mono many years ago, way before the 1.0 release. It was one of a couple of non-Microsoft implementations of .NET (or, if I was being pedantic and accurate, it was one of a variety of implementations of the CLI (Common Language Infrastructure) ECMA and ISO standards, of which .NET was the first and defining implementation).
The other one I played with quite a bit at the time seems to have dried up – it was a GNU initiative called Portable .NET.
Another .NET implementation that was pretty exciting in its day was Microsoft’s own SSCLI (the Shared Source Common Language Infrastructure). SSCLI was interesting because it was cross-platform, supporting Windows XP, FreeBSD and Mac OS X 10.2 (or at least that was what the 1.0 release supported). It came equipped with an academic license – no commercial work with it was allowed, but gave a full source base for an implementation of the CLI. A lot of the code was very similar to the .NET source code, although the garbage collector, among other portions, was different.
However SSCLI has stagnated since the 2.0 release in 2006. This is partly due to the fact that Visual Studio now allows you to step through the real .NET source, and so much of the benefit of seeing a whole bunch of the .NET source in SSCLI has diminished.
It did serve as an excellent educational resource though. I did a session on reverse-engineering .NET at an early Developer Developer Developer conference back in 2005 and showed the SSCLI version of ILDASM running within the Visual Studio debugger, allowing you to see the flow of execution through the various dump routines in the code base. Never happier than when neck-deep in a platform’s guts :-)
Anyway, Mono has come on in leaps and bounds since those early days and supports development of applications for iPhone (and iPod and iPad) as well as Android devices using MonoTouch and MonoDroid respectively. But the bread and butter of Mono comes in being able to run the same code base on various different platforms: Windows, OS X, Linux and many more besides. Clearly you have issues with deciding on what to do with the application UI – you can have different UIs on different platforms to have the app look native in each scenario, or you can go the cheap-and-cheerful approach of using something like GTK, where the app looks ‘slightly wrong’ on each platform.
I looked into all this sort of thing in a hefty paper i put together when looking at this at the tail end of 2009. The language used for the paper was Delphi Prism, but the principles of managed code familiar to any .NET or Mono programmer hold true for any language. If you want to review the content of the paper (and the suite of videos that accompanied it) you can visit the landing page or download the PDF paper directly.