Mono vs. .NET Framework: Public API Compatibility



In this post, I use the
NDepend assembly
comparison feature

to assess the public API compatibility between Mono 2.0
and the .NET Framework 3.5 SP1.


The assemblies considered
are: mscorlib,     System,     System.Core,     System.Messaging,     System.Runtime.Remoting,     System.Runtime.Serialization.Formatters.Soap,     System.Security,     System.ServiceProcess,     System.Transactions,     System.Web,     System.Web.Services,     System.Windows.Forms,     System.Xml,     System.Xml.Linq,     System.Configuration,     System.Configuration.Install,     System.Data.DataSetExtensions,     System.Data,     System.Data.Linq,     System.Data.OracleClient,     System.Design,     System.DirectoryServices,     System.Drawing.Design,     System.Drawing,     System.EnterpriseServices,     System.Management

We consider .NET
Framework bits as the newer build and the Mono ones as the older build. Thus
the following CQL Query
lists public types of the .NET Framework not supported by Mono:




The result is 1553 public
types not supported, to compare to 5720 public types supported. On
the following metric view, you can see these types in blue. Each
rectangle represents an assembly, namespace, type or method and the
size of the rectangle is proportional  to the underlying number of IL





With the following CQL
query it is easy to pinpoint that amongst not supported types, 499 are wrapper
of native win32 methods. We rely on the fact that such wrapper types are nested in outer types
named NativeMethods.


SELECT TYPES WHERE IsPublic AND WasAdded AND !NameLike “NativeMethods+”


The list of the 1054
types not supported and not win32 wrappers is available here.
This list includes:

  • a few Windows.Forms public implementation
  • the namespace System.Deployment.Internal.Isolation.Store,
  • the namespace System.Web.UI.WebControls.WebParts,
  • some ASP.NET/System.Web details like in Configuration, Security, Hosting, Caching,
  • some System.Security.Policy and Permissions
  • the namespace System.Security.AccessControl,
  • some CLR related public types
    like InsufficientMemoryException,
    MTAThreadAttribute, GCNotificationStatus
  • some System.Runtime.Remoting and Serialization
    types and the namespace System.Runtime.Remoting.Metadata.W3cXsd2001
  • obviously, many of the System.Runtime.InteropServices‘s types
  • a few types from System.Runtime.CompilerServices, System.Reflection, System.Globalization, System.IO
    and System.Threading
  • most of System.Diagnostics.SymbolStore’s
  • System.Web.UI.Design.WebControls‘s
    designer and editor (they muight be in a non-referenced assemblies ?)
  • some System.Data, System.Data.SqlTypes and Microsoft.SqlServer’s types
  • a few System.Xml.Serialization.Configuration’s
  • several namespaces of the
    assembly System.Core.dll, including System.Diagnostics.*,
    System.IO.*, System.Security.*,
    System.Threading.*, System.Management.Instrumentation.*
  • most of System.DirectoryServices.dll’s types
  • a few System.Transactions and System.Messaging’s types



On the other hand Mono
introduces 77 new public types all listed here. This list was obtained with the CQL query:



Most of them look
like implementation details that might be turned to internal, or that might be
useful for some advanced pure-Mono scenarios.




Concerning dependencies between
assemblies, the following matrix shows a few changes.

  • Cells with a red tick
    with a + means dependency in the .NET Fx absent in Mono,
  • Cells with a red tick
    with a – means dependency in Mono absent in the .NET Fx,
  • Cells with a red tick means
    coupling between 2 assemblies changed between Mono and the .NET Fx,






Finally I noticed that
Mono is much more lightweight in terms of IL instructions: 1 629 065 for Mono
and 3 591 830 for the .NET Fx. I have no explanation for this. The missing types
cannot explain such a difference (as we can see on the metric view above,
displayed with the #IL instructions metric). Maybe it is due to some Mono C#
compiler special behavior and optimization?


This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Patrick Smacchia

    wekempf, if an API is present at least it shows the motivation of Mono coder to implement it one day + you can still add the CQL condition:
    AND ! IsDirectlyUsing “System.NotImplementedException”

  • wekempf

    Just because an API is present, doesn’t mean it’s working. It’s possible some of those simply throw NotImplementedException, for instance, which could account for the difference in IL. Not saying this is the case, because I don’t know, but that does show a failing in a query like this.

  • Patrick Smacchia

    Krzysztof, because I wrote this post a few weeks ago before 2.2.

  • Krzysztof Kozmic
  • Patrick Smacchia

    >Would the comparision be closer if you compared .NET Framework 2.0 or 1.1?

    Chauncey, the fact is that concerning this API set (see the list of assemblies) there are no differences between .NET 2.0 and .NET 3.5.

    Also Mono API is based on .NET 2.0 API core and it is not relevant to compare it with .NET v1..

  • Pavels

    Mono is a .NET port, and it not includes implemintation of WPF, WCF, ….

  • Chauncey Smith

    This really begs the question. Is Mono surpose to be equal to which .NET Framework. Would the comparision be closer if you compared .NET Framework 2.0 or 1.1? Is there anywhere I can find that comparision?