C# Versions: What's Behind the Numbers and How It Works

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

C# Versions: What's Behind the Numbers and How It Works Under the Hood

\n\n

If you've ever browsed discussions on Stack Overflow, you've likely seen a question that has gathered thousands of views: "What are the correct version numbers for C#?". It seems simple enough — just open the documentation and you're done. But in reality, it's more confusing than it appears. Especially when you find out that C# 7.0 ships with .NET Framework 4.7, while C# 8.0 already comes with .NET Core 3.0. And why is C# 5.0 not tied to any specific .NET version at all? Welcome to a world where numbers are deceptive.

\n\n

In this article, we won't just list the versions. We'll look under the hood of the Roslyn compiler, figure out how version numbers relate to platforms, and show you, with real code examples, what features appeared in each version. Let's go!

\n\n

Why is the Question About C# Versions So Popular?

\n\n

The answer is simple: confusion between C# language versions and .NET versions. Many developers think that C# 7.0 is the same as .NET Framework 4.7. But that's not the case. The C# language lives its own life, and the .NET platform lives its own. The Roslyn compiler (also known as csc.exe) is the bridge between them. It takes C# code and turns it into IL code (Intermediate Language), which is then executed by the CLR (Common Language Runtime).

\n\n

Here's the key point: the same compiler version can support different language versions. For example, the compiler from Visual Studio 2019 can compile C# 7.0, 7.1, 7.2, 7.3, and 8.0 code — depending on the project settings. This is why there is so much confusion on Stack Overflow.

\n\n

A Brief History of C# Versions

\n\n

Let's run through the major milestones. I won't list all 12 versions in a row — instead, I'll highlight the ones that truly changed the game.

\n\n

C# 1.0 (2002) — The Beginning

\n

The first version of the language shipped with .NET Framework 1.0. It was a managed language with syntax similar to Java, but with unique features like properties and indexers. No LINQ, async/await, or generics. Simple, reliable, boring.

\n\n

C# 2.0 (2005) — Generics Change Everything

\n

This version brought generics, anonymous methods, iterators (yield return), and partial classes. It was a breakthrough: instead of writing ArrayList with boxing/unboxing, you could use List<T>. Performance skyrocketed.

\n\n
// C# 2.0 — generics\nList<int> numbers = new List<int> { 1, 2, 3 };\nnumbers.ForEach(n => Console.WriteLine(n * 2)); // Anonymous method\n
\n\n

C# 3.0 (2007) — LINQ and Lambdas

\n

The most revolutionary version. LINQ (Language Integrated Query) changed the approach to working with data. Lambda expressions, extension methods, anonymous types, object initializers — all of this appeared here. The Roslyn compiler wasn't born yet, but C# 3.0 laid the foundations for the future.

\n\n
// C# 3.0 — LINQ and lambdas\nvar evenNumbers = Enumerable.Range(1, 10)\n    .Where(x => x % 2 == 0)\n    .Select(x => x * x);\nConsole.WriteLine(string.Join(", ", evenNumbers)); // 4, 16, 36, 64, 100\n
\n\n

C# 5.0 (2012) — Async/await

\n

Asynchronous programming became simpler than ever. async and await are not just syntactic sugar. The compiler generates a complex state machine that manages threads. If you're writing in C# 5.0 and above, you can forget about manually managing BeginInvoke and EndInvoke.

\n\n
// C# 5.0 — async/await\nasync Task<string> FetchDataAsync(string url)\n{\n    using (var client = new HttpClient())\n    {\n        return await client.GetStringAsync(url);\n    }\n}\n
\n\n

C# 6.0 (2015) — Sugar for Everyday Use

\n

This version didn't bring new paradigms, but it made code cleaner: string interpolation<

Blogs

Book Recommendations