Taking a look at the ECMA-335 Standard for .NET

It turns out that the .NET Runtime has a technical standard (or specification), known by its full name ECMA-335 - Common Language Infrastructure (CLI) (not to be confused with ECMA-334 which is the ‘C# Language Specification’). The latest update is the 6th edition from June 2012.

The specification or standard was written before .NET Core existed, so only applies to the .NET Framework, I’d be interested to know if there are any plans for an updated version?

The rest of this post will take a look at the standard, exploring the contents and investigating what we can learn from it (hint: lots of low-level details and information about .NET internals)

Why is it useful?

Having a standard means that different implementations, such as Mono and DotNetAnywhere can exist, from Common Language Runtime (CLR):

Compilers and tools are able to produce output that the common language runtime can consume because the type system, the format of metadata, and the runtime environment (the virtual execution system) are all defined by a public standard, the ECMA Common Language Infrastructure specification. For more information, see ECMA C# and Common Language Infrastructure Specifications.

and from the CoreCLR documentation on .NET Standards:

There was a very early realization by the founders of .NET that they were creating a new programming technology that had broad applicability across operating systems and CPU types and that advanced the state of the art of late 1990s (when the .NET project started at Microsoft) programming language implementation techniques. This led to considering and then pursuing standardization as an important pillar of establishing .NET in the industry.

The key addition to the state of the art was support for multiple programming languages with a single language runtime, hence the name Common Language Runtime. There were many other smaller additions, such as value types, a simple exception model and attributes. Generics and language integrated query were later added to that list.

Looking back, standardization was quite effective, leading to .NET having a strong presence on iOS and Android, with the Unity and Xamarin offerings, both of which use the Mono runtime. The same may end up being true for .NET on Linux.

The various .NET standards have been made meaningful by the collaboration of multiple companies and industry experts that have served on the working groups that have defined the standards. In addition (and most importantly), the .NET standards have been implemented by multiple commercial (ex: Unity IL2CPP, .NET Native) and open source (ex: Mono) implementors. The presence of multiple implementations proves the point of standardization.

As the last quote points out, the standard is not produced solely by Microsoft:

Companies and Organizations that Participated

There is also a nice Wikipedia page that has some additional information.

What is in it?

At a high-level overview, the specification is divided into the following ‘partitions’ :

  • I: Concepts and Architecture
    • A great introduction to the CLR itself, explaining many of the key concepts and components, as well as the rationale behind them
  • II: Metadata Definition and Semantics
    • An explanation of the format of .NET dll/exe files, the different sections within them and how they’re laid out in-memory
  • III: CIL Instruction Set
    • A complete list of all the Intermediate Language (IL) instructions that the CLR understands, along with a detailed description of what they do and how to use them
  • IV: Profiles and Libraries
    • Describes the various different ‘Base Class libraries’ that make-up the runtime and how they are grouped into ‘Profiles’
  • V: Binary Formats (Debug Interchange Format)
    • An overview of ‘Portable CILDB files’, which give a way for additional debugging information to be provided
  • VI: Annexes
    • Annex A - Introduction
    • Annex B - Sample programs
    • Annex C - CIL assembler implementation
    • Annex D - Class library design guidelines
    • Annex E - Portability considerations
    • Annex F - Imprecise faults
    • Annex G - Parallel library

But, working your way through the entire specification is a mammoth task, generally I find it useful to just search for a particular word or phrase and locate the parts I need that way. However if you do want to read through one section, I recommend ‘Partition I: Concepts and Architecture’, at just over 100 pages it is much easier to fully digest! This section is a very comprehensive overview of the key concepts and components contained within the CLR and well worth a read.

Also, I’m convinced that the authors of the spec wanted to help out any future readers, so to break things up they included lots of very helpful diagrams:

Type System.png

For more examples see:

On top of all that, they also dropped in some Comic Sans 😀, just to make it clear when the text is only ‘informative’:

Informative Text

How has it changed?

The spec has been through 6th editions and it’s interesting to look at the changes over time:

Edition Release Date CLR Version Significant Changes
1st December 2001 1.0 (February 2002) N/A
2nd December 2002 1.1 (April 2003)  
3rd June 2005 2.0 (January 2006) See below (link)
4th June 2006   None, revision of 3rd edition (link)
5th December 2010 4.0 (April 2010) See below (link)
6th June 2012   None, revision of 5th edition (link)

However, only 2 editions contained significant updates, they are explained in more detail below:

  • Support for generic types and methods (see ‘How generics were added to .NET’)
  • New IL instructions - ldelem, stelem and unbox.any
  • Added the constrained., no. and readonly. IL instruction prefixes
  • Brand new ‘namespaces’ (with corresponding types) - System.Collections.Generics, System.Threading.Parallel
  • New types added, including Action<T>, Nullable<T> and ThreadStaticAttribute
  • Type-forwarding added
  • Semantics of ‘variance’ redefined, became a core feature
  • Multiple types added or updated, including System.Action, System.MulticastDelegate and System.WeakReference
  • System.Math and System.Double modified to better conform to IEEE

Microsoft Specific Implementation

Another interesting aspect to look at is the Microsoft specific implementation details and notes. The following links are to pdf documents that are modified versions of the 4th edition:

They all contain multiple occurrences of text like this ‘Implementation Specific (Microsoft)’:

Microsoft Specific Implementation Notes - Partition I

More Information

Finally, if you want to find out more there’s a book available (affiliate link):