In What would you choose for your project between .NET and Java at this point in time? I say that I would consider the "Will you always deploy to Windows?" the single most important technical decision to make up front in a new web project, and if the answer is "no", I would recommend Java instead of .NET.

A very common counter-argument is that "If we ever want to run on Linux/OS X/Whatever, we'll just run Mono"1, which is a very compelling argument on the surface, but I don't agree for several reasons.


OpenJDK and all the vendor supplied JVM's have passed the official Sun TCK ensuring things work correctly.  I am not aware of Mono passing a Microsoft TCK.
Mono trails the .NET releases.  What .NET-level is currently fully supported?
Does all GUI elements (WinForms?) work correctly in Mono?
Businesses may not want to depend on Open Source frameworks as the official plan B.


I am aware that with the new governance of Java by Oracle, the future is unsafe, but e.g. IBM provides JDK's for many platforms, including Linux.  They are just not open sourced.

So, under which circumstances is Mono a valid business strategy for .NET-applications?



1Mark H summarized it as: "If the claim is that "I have a windows application written in .NET, it should run on mono", then not, it's not a valid claim - but Mono has made efforts to make porting such applications simpler."

Sparkie's answer got it, let me complement a little.

".NET is cross platform" is too much of an ambiguous statement as both the framework and the world it was originally created for have changed and evolved.   

The short answer is: 

The underlying engine that powers .NET and its derivatives, the Common Language Infrastructure Standard, is cross-platform and as if you want to make your code go to multiple platforms, you need to plan on using the right APIs on the right platform to deliver the best experience on each platform.

The CLI family has not tried the "Write Once, Run Anywhere" approach, as the differences from a phone to a mainframe are too big.   Instead a universe of API and runtime features that are platform-specific has emerged to give developers the right tools to create great experiences in each platform.

Think of it: programmers no longer target Windows PCs or Unix Servers.   The world, now more than ever is surrounded by fascinating platforms from PCs, to gaming consoles, to powerful phones, to set-top boxes, to big servers and distributed clusters of machines.  A one-size fits on all platform would merely feel bloated on tiny devices, and feel underpowered on large systems.

The Microsoft's .NET Framework product is not cross platform, it only runs on Windows.  There are variations of the .NET Framework from Microsoft that run on other systems like the Windows Phone 7, the XBox360 and browsers through Silverlight, but they are all slightly different profiles.   

Today you can target every major mainstream OS, phone, mobile device, embedded system and server with .NET-based technologies.   Here is a list that shows which CLI implementation you would use in each case (this list is not comprehensive, but should cover 99% of the cases):


x86 and x86-64 based PC computers:


running Windows -> Typically you run .NET or Silverlight but you can also use full Mono here.
running Linux, BSD or Solaris -> You run full Mono or Silverlight
running MacOS X -> You run full Mono or Silverlight
running Android -> You run Mono/Android subset

ARM computers:


Running Windows Phone 7: you run Compact Framework 2010
Running Windows 6.5 and older: you run the old Compact Framework
Android devices: you run Mono/Android

PowerPC computers:


You run full Mono for full Linux, BSD or Unix operating systems
You run embedded Mono for PS3, Wii or other embedded systems.
On XBox360, you run CompactFramework

S390, S390x, Itanium, SPARC computers:


You run full Mono

Other embedded operating systems:


You run .NET MicroFramework or Mono with the mobile profile.



Depending on your needs the above might be enough or not.   You will hardly get the same source code to run everywhere.   For example, XNA code wont run on every desktop, while .NET Desktop software wont run on XNA or the phone.   You typically need to make changes to your code to run in other profiles of the .NET Framework.   Here are some of the profiles I am aware of:


.NET 4.0 Profile
Silverlight Profile 
Windows Phone 7 Profile
XBox360 Profile
Mono core Profile - follows the .NET profile and is available on Linux, MacOS X, Solaris, Windows and BSD.
.NET Micro Framework
Mono on iPhone profile
Mono on Android Profile
Mono on PS3 Profile
Mono on Wii Profile
Moonlight profile (compatible with Silverlight)
Moonlight extended profile (Silverlight + full .NET 4 API access)


So each one of those profiles is actually slightly different, and this is not a bad thing.   Each profile is designed to fit on its host platform and expose the APIs that make sense, and remove the ones that do not make sense.

For instance, Silverlight's APIs to control the host browser do not make sense on the phone.   And shaders in XNA make no sense on PC hardware that lacks the equivalent support for it.

The sooner you realize that .NET is not a solution to isolating the developer from the underlying capabilities of the hardware and the native platform, the better off you will be.

That begin said, some APIs and stacks are available in multiple platforms, for example ASP.NET can be used on Windows, on Linux, on Solaris, on MacOS X because those APIs exist both on .NET and Mono.   ASP.NET is not available on some of Microsoft's supported platforms like XBox or Windows Phone 7 and is not supported either on other platforms that Mono supports like the Wii or the iPhone.

The following information is only correct as of November 21st, and many things in the Mono world will likely change.

The same principles can be applied to other stacks, a full list would require a proper table, which I have no idea of how to present here, but here is a list of technologies that might not be present on a particular platform.   You can assume that anything not listed here is available (feel free to send me edits for things I missed):

Core Runtime Engine [everywhere]


Reflection.Emit Support [everywhere, except WP7, CF, Xbox, MonoTouch, PS3]
CPU SIMD support [Linux, BSD, Solaris, MacOS X; Soon PS3,  MonoTouch and MonoDroid]
Continuations - Mono.Tasklets [Linux, BSD, Solaris, MacOS, PS3, Wii]
Assembly Unloading [Windows only]
VM Injection [Linux, BSD, MacOS X, Solaris]
DLR [Windows, Linux, MacOS X, Solaris, MonoDroid]
Generics [some limitations on PS3 and iPhone].


Languages


C# 4 [everywhere]
C# Compiler as a Service (Linux, MacOS, Solaris, BSD, Android)
IronRuby [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]
IronPython [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]
F# [everywhere, execpt WP7, CF, Xbox, MonoTouch, PS3]


Server Stacks


ASP.NET [Windows, Linux, MacOS, BSD, Solaris]
ADO.NET [everywhere]
LINQ to SQL [everywhere]
Entity Framework [everywhere]
Core XML stack [everywhere]


XML serialization [everywhere, except WP7, CF, Xbox)

LINQ to XML (everywhere)
System.Json [Silverlight, Linux, MacOS, MonoTouch, MonoDroid]
System.Messaging [Windows; on Linux, MacOS and Solaris requires RabbitMQ]
.NET 1 Enterprise Services [Windows only]
WCF [complete on Windows; small subset on Silverlight, Solaris, MacOS, Linux, MonoTouch, MonoDroid]
Windows Workflow [Windows only]
Cardspace identity [Windows only]


GUI stacks


Silverlight (Windows, Mac, Linux - with Moonlight)
WPF (Windows only)
Gtk# (Windows, Mac, Linux, BSD)
Windows.Forms (Windows, Mac, Linux, BSD)
MonoMac - Native Mac Integration (Mac only)
MonoTouch - Native iPhone Integration (iPhone/iPad only)
MonoDroid - Native Android Integration (Android only)
Media Center APIs - Windows only
Clutter (Windows and Linux)


Graphic Libraries


GDI+ (Windows, Linux, BSD, MacOS)
Quartz (MacOS X, iPhone, iPad)
Cairo (Windows, Linux, BSD, MacOS, iPhone, iPad, MacOS X, PS3, Wii)


Mono Libraries - Cross Platform, can be used in .NET but require manually building


C# 4 Compiler as a Service
Cecil - CIL Manipulation, workflow, instrumentation of CIL, Linkers
RelaxNG libraries
Mono.Data.* database providers
Full System.Xaml (for use in setups where .NET does not offer the stack)


MonoTouch means Mono running on iPhone;   MonoDroid means Mono running on Android;   PS3 and Wii ports only available to Sony and Nintendo qualified developers.

I apologize for the lack of formality.
