In our last installment, we explored some of C#'s more surprising behaviors.
But C# is only part of a much bigger story.
A story involving multiple programming languages, competing user interface frameworks, a rather complicated relationship with open source, and enough product renaming to keep an entire marketing department employed for decades.
Welcome to .NET.
Or .NET Framework.
Or .NET Core.
Or just .NET again.
We'll get to that.
1. In the Beginning, There Was Windows
When Microsoft launched .NET Framework in 2002, it represented an ambitious new direction for Windows development.
At its heart was the Common Language Runtime (CLR), an execution environment providing garbage collection, memory management, exception handling, and other services that developers previously had to manage themselves.
Instead of compiling directly to native machine code, supported languages generally compiled into Common Intermediate Language (CIL), which the runtime could then execute using just-in-time compilation.
That was a pretty powerful idea.
Multiple programming languages could share a runtime, a type system, and an extensive library ecosystem.
A developer could write a library in one language and consume it from another.
Naturally, Microsoft decided that one programming language wasn't enough.
2. C#, VB.NET, and F#: Three Languages Walk Into a Runtime
C# was the obvious flagship.
Modern syntax, strong typing, object-oriented programming, and enough familiarity with Java and C++ to make developers feel at home.
But Microsoft had another a constituency to consider.
Visual Basic developers.
VB.NET: It's Visual Basic, Jim, but Not as We Know It
Visual Basic had been wildly popular for Windows application development.
Its selling point was accessibility. You could drag controls onto a form, write some event handlers, and have a functioning application without spending six months studying Windows internals.
For a generation of developers, Visual Basic was how you built business applications, full stop.
So Microsoft brought Visual Basic into .NET.
Except VB.NET wasn't simply the old Visual Basic with a new runtime.
It was substantially redesigned.
The old VB6 world included COM-based components, default form instances, and a programming model that was quite different from the CLR's object-oriented architecture.
VB.NET introduced a new type system, inheritance, structured exception handling, and the other capabilities required to participate in .NET.
That was great for architectural consistency.
Less great for developers discovering that their existing VB6 applications weren't going to migrate quite as effortlessly as they'd hoped.
Today, Visual Basic still exists in modern .NET.
But Microsoft has made its direction clear: VB will remain supported and stable, without aggressively expanding into new workloads or pursuing every new language feature introduced in C#.
Which is a polite way of saying:
"You are tolerated, former incumbent."
F#: Wait, We Also Have a Functional Language?
Then there's F#.
While C# and VB.NET largely embraced object-oriented programming, F# arrived with a functional-first philosophy.
Immutability by default.
Pattern matching.
Type inference.
Functions as first-class citizens.
And a syntax that looks refreshingly different from the sea of curly braces elsewhere in the ecosystem.
What makes F# particularly interesting is that it isn't a separate runtime universe.
It uses .NET too.
An F# library can be consumed by C# code. Both can use much of the same underlying framework.
That's convenient.
You can write enterprise business logic in C#, functional transformations in F#, and maintain an application in VB.NET, all within the same general ecosystem.
Although anyone who has actually maintained a multilingual solution will tell you that technically interoperable and pleasant to maintain are not necessarily synonyms.
The fascinating part: .NET was designed to make programming languages less important than the runtime and libraries they shared.
Twenty-four years later, C# overwhelmingly dominates the ecosystem, VB remains supported, and F# continues to serve developers who appreciate its different approach.
One platform. Three officially supported languages. Three rather different philosophies.
3. Windows Forms: Just Drag the Button On Form1
Let's talk about building user interfaces.
For many developers in the early .NET era, Windows Forms was one of the platform's most appealing features.
Open Visual Studio.
Create a form.
Drag a button onto it.
Double-click the button.
Write some code.
Keep the default icon.
Congratulations. You have a Windows application.
WinForms was wonderfully pragmatic.
Its programming model was event-driven and closely tied to traditional Windows desktop controls.
For business applications, internal tools, and database frontends, it was often exactly what developers needed.
Of course, Microsoft eventually decided that Windows application development needed something more sophisticated.
Enter WPF.
4. WPF and XAML: What if Buttons Were XML?
In 2006, Microsoft introduced Windows Presentation Foundation as part of .NET Framework 3.0.
WPF brought an entirely different approach to desktop UI development.
Instead of primarily positioning controls in a visual designer and attaching event handlers, developers could describe interfaces declaratively using XAML.
Extensible Application Markup Language.
Because apparently XML hadn't yet appeared in enough places.
To be fair, XAML enabled some powerful ideas.
Data binding.
Reusable styles and templates.
Resolution-independent layouts.
Rich graphics and animation.
And better separation between the visual interface and application logic.
WPF could produce interfaces that were dramatically more sophisticated than traditional WinForms applications.
It also introduced concepts such as dependency properties, routed events, and elaborate binding mechanisms.
Things that were pretty cool, right up until a binding silently failed and you spent the afternoon trying to understand why a button was disabled.
Then came the familiar Microsoft ecosystem question:
Which UI technology should you actually use?
WinForms was still around.
WPF was supposed to be the modern alternative.
Someone at Microsoft said: "we're gonna need a bigger boat".
SO they came up with Silverlight, UWP, WinUI, and eventually .NET MAUI.
And here's an important distinction: XAML isn't itself a competing UI framework. It's a declarative markup language used by multiple frameworks, including WPF, WinUI, and .NET MAUI, with differences between their implementations.
(And what about Xamarin? "THERE WAS NEVER A XAMARIN").
Today, WinForms and WPF remain supported on modern .NET.
WinUI is Microsoft's primary recommendation for new general-purpose Windows desktop applications.
And .NET MAUI targets multiple platforms, including Windows, macOS, Android, and iOS.
Yes, a platform famous for introducing alternatives has managed to retain several of them simultaneously.
The lesson: Microsoft rarely eliminates an old development technology simply because a newer one exists. Sometimes the future arrives, and the past just moves into the spare bedroom. Except for Xamarin.
5. Plot Twist: .NET Escapes Windows
For much of its early history, Microsoft's official .NET Framework was closely associated with Windows.
But an important part of this story happened outside Microsoft.
The Mono project began developing an open-source, cross-platform implementation of .NET in the early 2000s.
It demonstrated that .NET technology could live beyond Windows, including on Linux.
This was a mic drop moment.
Because the underlying .NET concepts were not inherently Windows-specific, even though many framework APIs and application technologies were.
Years later, Microsoft began moving toward a much more open development strategy.
It open-sourced major pieces of its developer tooling and runtime ecosystem.
Then, in 2016, .NET Core 1.0 arrived.
Open source.
Cross-platform.
Designed with modern server workloads, cloud deployment, and modularity in mind.
A Microsoft development platform running naturally on Linux would once have seemed like a fairly elaborate practical joke.
Now it was part of the official strategy.
But there was a catch.
.NET Core wasn't simply a cross-platform copy of everything in .NET Framework.
It was a different implementation with different APIs and initially a smaller surface area.
Some applications could migrate relatively easily.
Others depended on Windows-specific technologies, legacy framework components, or third-party libraries that weren't available.
And some simply couldn't be moved without significant rewrites.
But the direction was clear.
.NET was no longer synonymous with Windows.
Or proprietary software.
Which brings us to the naming department.
6. The Naming Department Has Entered the Chat
Let's recap.
We started with .NET Framework.
Then Microsoft introduced .NET Core.
Meanwhile, we had .NET Standard, which wasn't another runtime at all, but an API specification designed to help libraries work across different .NET implementations.
Then, after .NET Core 3.1, Microsoft released...
.NET 5.
Not .NET Core 4.
Not .NET Framework 5.
Just .NET 5.
Why skip four?
Partly to avoid confusion with the existing .NET Framework 4.x product line.
So Microsoft solved one naming conflict by skipping a number and dropping a word.
There was probably a PowerPoint presentation involved.
Since then, modern .NET has continued with annual version releases, reaching .NET 10 in November 2025.
Meanwhile, the original .NET Framework continues to exist, with version 4.8.1 supported on Windows.
And just to complete the picture, ASP.NET Core retains the word "Core" even though the main runtime dropped it.
So today:
- .NET Framework means the original Windows-only implementation.
- .NET means the modern open-source, cross-platform implementation.
- .NET Standard describes a compatibility-oriented API specification, not a runtime.
- ASP.NET Core is the modern web framework, despite the runtime's naming change.
- .NET Core is the former name of what evolved into modern .NET.
Now let's brace ourselves for .NET Copilot which is almost certainly cooking somewhere in Redmond.
7. And Then There's PowerShell
Here's a part of the .NET ecosystem that doesn't always get enough attention.
PowerShell.
Most people think of it as a command-line shell and scripting language, particularly associated with Windows administration.
Not wrong.
But PowerShell is also deeply connected to .NET.
Unlike traditional Unix shells, which primarily pass text between commands, PowerShell pipelines can pass structured objects.
Actual objects, with properties and methods.
Those objects are frequently .NET objects.
Which means a PowerShell script can access parts of the .NET ecosystem directly.
Want to work with filesystem APIs?
Use .NET objects.
Need regular expressions?
They're available.
Want to instantiate framework classes or call static methods?
You can do that too.
PowerShell is, in many ways, a .NET automation environment disguised as a shell.
And naturally, it has its own version of the great .NET identity crisis.
Windows PowerShell 5.1 runs on the original .NET Framework.
Modern PowerShell 7 runs on modern .NET and supports Windows, Linux, and macOS.
Both can exist on the same Windows machine.
And they can behave differently when scripts depend on incompatible modules or framework APIs.
So now we have two PowerShell families corresponding to two .NET families.
At this point, the family tree needs a database.
But underneath the confusing history lies something genuinely powerful: an administrator can write a script that manipulates rich runtime objects, while developers can expose functionality that PowerShell can consume without inventing an entirely separate scripting interface.
It's one of .NET's more underappreciated achievements.
8. So What Exactly Is .NET?
After all that, it's worth asking the obvious question.
Is .NET a programming language?
No.
An operating system?
Also no.
A framework?
Yes, but that answer is incomplete.
A runtime?
Yes, but still incomplete.
.NET is better understood as an entire development platform.
It includes runtimes, compilers, standard libraries, SDKs, development tools, and application frameworks.
It supports different languages and workloads.
You can build web APIs, desktop applications, cloud services, mobile applications, games, and command-line tools.
The current platform is powerful.
And the shift from the original Windows-centric .NET Framework to today's open-source implementation is one of Microsoft's most significant technological transformations.
There is also a wonderfully ironic outcome.
Microsoft spent years building an ecosystem closely associated with Windows development.
Then it invested heavily in making that ecosystem work without Windows.
Developers can now build a C# application on Linux, deploy it in a Linux container, run it in the cloud, and never touch a Windows desktop.
Which would have sounded strange in 2002.
Somehow, all those identities coexist.
Not always elegantly.
Not always compatibly.
And certainly not under a naming scheme that anyone would describe as intuitive.
But the result is impressive.
