Part 1 of a 4-part series. A link to part 2 is at the bottom.
Java has been my primary bread-and-butter for more than 15 years. However, over the past five years, my two most recent companies have been mixed shops that use both Java and C# to some degree.
My initial impression was that “C#-as-a-language” is about five years ahead of Java, but “.NET-as-a-ecosystem” is a decade or more behind. So I learned… just enough. Last year when Microsoft open-sourced the upcoming CoreCLR, issued a patent covent for it, and announced plans for official Linux and OS X support, my personal interest level skyrocketed. C# and .NET have since become a main focus of my personal development over the past year. I’m extremely interested to see how Microsoft’s changing mentality trickles into its wider community, and accelerates the evolution of that ecosystem as a whole.
This new legal model coincides with new versions of .NET components. These aren’t just incremental updates, they represent a developer experience fundamentally different from previous versions. Moreover, they’re still in active development, and don’t yet have an official release date as of this writing.
So there are a ton of brand new eyeballs on .NET right now, coming from Hacker News, Reddit, and other online communities. A lot of the resources they might use to learn about .NET are outdated, at least in terms of this new stuff. Moreover, some of the new approaches borrowed from other communities might seem alien to longtime .NET developers. There’s a lot to learn, for newbies and veterans both, and no good “Rosetta Stone” bridging the gap between them. Here, I’ll talk about the major components from the perspective of Java or JavaScript veterans who are newbies to .NET.
“.NET Framework” vs. “.NET Core” vs. “Mono”
.NET Framework
The Java world has the Java Virtual Machine (JVM), an application that executes bytecode. This bytecode might come from Java source, or from alternative languages like Groovy or Scala. There’s also the concept of a Java Runtime Environment (JRE), which encompasses the JVM along with a deep standard library.
The Microsoft model is very similar, executing bytecode with the Common Language Runtime (CLR). Bytecode typically comes from C# source, but sometimes Visual Basic or F# instead. The “.NET Framework” is an umbrella term that likewise includes the CLR and a standard library.
.NET Core
The Java world has an open source implementation (OpenJDK) of about 99% of the JRE. There are some odd bits around cryptography or GUI development which will not or cannot be open sourced, so if you need those then you must use a proprietary JRE build from Oracle.
Going forward, a Microsoft-backed foundation will offer an open source implementation called “.NET Core“. This consists of a CLR runtime (i.e. “CoreCLR”), and a subset of the standard library. The full-blown “.NET Framework“, which includes desktop GUI libraries and support for older versions of ASP.NET, will continue to be a proprietary bundle. The full .NET Framework remains tied to Windows, but the new .NET Core subset will be officially supported on Linux and OS X as well.
Although analogous to the differences between OpenJDK and Oracle JDK, the differences between .NET Core and .NET Framework are much more profound. As mentioned already, cross-platform support will only be available with .NET Core. Unfortunately, you still can’t write a desktop Windows app using WPF (i.e. an analogue to JavaFX) and magically run it as an OS X or Linux desktop app.
On the other hand, .NET Core is designed to use the standard library in a more sophisticated way. The full proprietary .NET Framework is an all-or-nothing monolith, similar to the Java Runtime Environment in size and manner of use. Meanwhile, .NET Core is fundamentally modular. You can isolate only those portions of the standard library that your application actually uses. If you’ve been hearing about “Project Jigsaw” coming with Java 9 next year, but aren’t sure what that’s about, then .NET Core provides a glimpse of Java’s future today.
What this means is that .NET Core allows you to bundle the runtime itself into your deployment artifacts. Java developers are growing accustomed to their build tools generating single-file “uber JAR’s”, with all of an application’s third-party dependencies bundled. However, you still need the correct JRE installed on the target machine(s). The JRE is over a hundred megs, so if you want to embed that too, then you’re probably talking about container technologies like Docker. With .NET Core, your runtime environment can be stripped down to tens of megabytes rather than hundreds. So the new build tools make it easy to bundle .NET itself into your application deliverable, with no need for .NET to be present on the target machine(s). This isn’t quite as dead simple as Golang or Rust, which compiles everything into a static executable with no VM at all, but it’s still a huge leap forward in devop-friendliness.
Mono
Off to the side there is Mono, an open-source alternative .NET implementation that’s been around 10 years. Mono is not a Microsoft project, but rather is sponsored by Xamarin, a company specializing in letting developers use C# to write Android and iOS mobile apps.
Mono has the same limitations as .NET Core, in that it doesn’t try to implement most of the desktop GUI features that are tightly coupled with Windows. In the long term, Mono and .NET Core may effectively merge together. Either way, it seems like Mono going forward will be of interest primarily to mobile app developers, and people running older .NET applications on Linux.
Conclusion
For writing traditional Windows desktop apps, very little is changing. The .NET Framework remains proprietary, monolithic, and tightly-coupled with Windows. However, the new open source .NET Core offers an intelligent modular approach to deploying server-side code to Windows, OS X, and Linux environments.
In the next section of this four-part overview, we’ll look at the ASP.NET framework and the development and build tools offered under its umbrella.