C# News from the Future: What If...?
Language design is one of the great spectator sports for developers. Everyone has a favourite feature they would add and a pet annoyance they would remove. Here is a short, speculative tour of "what if" questions for C#. Some of these ideas are the kind a language might one day adopt; others are simply useful thought experiments. None of this is a prediction, just a look at the pressure points in everyday code.
What if asynchronous code looked synchronous?
Anyone who has chained callbacks knows the pain. Fetch a page, then parse it, then save it, with each step nested inside the previous one:
Download(url, html =>
Parse(html, doc =>
Save(doc, () =>
Console.WriteLine("done"))));
Now imagine writing the same logic as straight-line code, with the compiler turning it into the callbacks for you:
var html = await Download(url);
var doc = await Parse(html);
await Save(doc);
Console.WriteLine("done");
The idea is that the method pauses at each waiting point and resumes later without blocking a thread. Exceptions flow with normal try/catch, loops work as expected, and the reader sees the order of events instead of the plumbing. The shape of code you can read top to bottom matters more than it seems.
What if you could match on shape?
Much of our code asks "what kind of thing is this?" and then does something different for each answer. Today that is a chain of is checks and casts:
if (shape is Circle)
{
var c = (Circle)shape;
return Math.PI * c.Radius * c.Radius;
}
else if (shape is Rectangle)
{
var r = (Rectangle)shape;
return r.Width * r.Height;
}
What if a switch could test the type and give you the typed variable at the same time? You would write the case, name the variable, and the cast would disappear. Better still, what if the compiler could tell you when you forgot a case? Functional languages have enjoyed this for years, and many .NET developers look at it with envy.
What if immutability were the default?
Bugs love shared mutable state. A small class used as a value carries a hidden risk each time someone adds a setter:
public class Money
{
public decimal Amount { get; set; }
public string Currency { get; set; }
}
Today you make something immutable by writing the constructor, the read-only fields and the "with" methods by hand. What if declaring a type as a plain value with a few fields gave you equality, a readable string form and a simple way to make a modified copy, all without a page of boilerplate? Immutable data is far easier to reason about, to share between threads and to test, so language support would reduce a whole class of mistakes.
What if null were a deliberate choice?
Few mistakes are as common as the dreaded null reference. What if a reference type could not hold null unless you said so explicitly, and the compiler warned when you dereferenced something that might be missing? The idea is to move one of the most frequent runtime failures to compile time. Even without such support, you can lean on guard clauses and return empty collections rather than nulls.
What if less ceremony were required?
A simple program in C# starts with namespaces, a class and a static method. Compare that with scripting languages where a line is a program. What if the language let you write top-level statements for small utilities and still compile them to the same thing underneath? Beginners would meet fewer concepts before seeing a result, and experienced developers would write quick tools without ritual.
The same thinking applies to data. Creating a small bundle of values just to return two numbers from a method is clumsy. A lightweight tuple type would let you write:
var (min, max) = Range(numbers);
and move on.
What if testing hooks were built in?
Testability keeps colliding with static calls and sealed types. Tools like isolating code with Moles and Fakes exist precisely because the language does not make replacement of a static call easy. What if the language encouraged small seams, such as treating a function as a first-class dependency? You can already do some of this by passing delegates, as shown in funcy testing, and a language that made that cheaper would nudge everybody towards better design.
What these wishes have in common
- They remove noise. Each idea trades ceremony for intent.
- They move errors earlier. Forgotten cases, nulls and mutation bugs become compile-time messages.
- They borrow from other languages. Almost nothing here is new; C# keeps learning from functional and dynamic languages.
- They are about reading. Code is read many more times than written.
How to prepare for any future
- Learn one functional language, even briefly. It changes how you write loops and conditionals.
- Write small, pure methods that take values and return values.
- Prefer immutable types for data.
- Keep your options open by avoiding clever tricks that depend on today's limitations.
Whether or not any of these what-ifs arrive, practising the style they encourage makes your present code better. That is the quiet advantage of daydreaming about languages. For more on how to keep learning without waiting for tools, see how developers really learn.
More .NET guides
- Moles and Pex: Isolating .NET Code and Generating Tests (Now Fakes and IntelliTest)
- Building a Web Framework Is the New Black
- Funcy Testing: Using Func and Action Instead of Interfaces
- MEF: Making Extensibility Fun
- A Gentle Introduction to WCF
- Tinyweb Series, Part 1: Getting Started
- Tinyweb Series, Part 2: Building APIs
- Tinyweb Series, Part 3: Dependency Injection and Filters
- Tinyweb Series, Part 4: Views, View Models and Model Binding
- Tinyweb Series, Part 5: The To-Do Demo
- The Ordered Jobs Kata: Dependency Sorting with TDD in C#
- JavaScript: It's Up Your Sleeve
- What's After Unit Testing?
- The "If It Isn't Broken, Don't Fix It" Mentality
- Are You Failing Enough?
- Don't Bother Rewriting It: The Case for Gradual Refactoring
- Was Dave a Genius? Lessons from a Legacy Codebase
- Preston Tweetup: Why Developer Meetups Matter
- How Developers Really Learn
- Sustainable Side Projects: Keeping Personal Code Alive
- Parallel.For and Silver Bullets
Looking for a software partner? Browse the independent directory of French tech companies (web agencies, IT consultancies, software publishers; the directory itself is in French).