Introduction
I have worked with the .NET platform for over 10 years. My focus shifted, but I still follow the news. Here is my personal summary of .NET Conf 2024!
.NET Conf 2024 just finished, it was packed with information and a new .NET version. If you feel overwhelmed by the amount of talks, keep on reading. Because In this summary I am focusing on the topics that I am interested in to give you a little overview. This is what I am going to talk about:
- What’s new in C#13 (Watch here)
- C#’s best features you might not be using (Watch here)
- What’s new in WinUI and Windows App SDK 1.6 (Watch here)
- Modern WinForms Development with .NET 9 (Watch here)
- Build hybrid apps with .NET MAUI (Watch here)
- API-ly ever after: OpenAPI in .NET 9 (Watch here)
- What’s new in Visual Studio 2022 for .NET developers (Watch here)
- What’s new in the .NET Runtime, Libraries, & SDK (Watch here)
- Performance improvements in .NET 9 (Watch here)
- What’s new in .NET MAUI in .NET 9 (Watch here)
- MVVM Building Blocks for WinUI and WPF Development (Watch here)
I want compress around 5 hours and 30 minutes of video information into this article. Sometimes, context might be missing although I try to not let that happen. You have the full videos linked in any case to get more information any time you need it.
As you can see, my focus doesn’t include much of AI and Azure. Since I mostly use .NET in a private environment for personal projects, I have no need for these topics and I am also not really interested in them.
If you want to watch the full conference or single talks, then head over to the dotnet Youtube channel. All session are published there!
What’s new in C# 13
Let’s be honest: You can do most of the stuff with C# that other major languages offer. Probably not as short as others but it’s possible. So the most recent features and changes are more likely only relevant to a smaller audience.
params collection
Before C# 13, the params
keyword expected an array to follow. Now you can use it with collection types like IEnumerable<T>
, ICollection<T>
, or IReadOnlyList<T>
.
// before C# 13
public void Add(params int[] items)
{
...
}
// C# 13
public void Add(params IEnumerable<int> items)
{
...
}
New lock object
Locking is usually done by using an object to create a lock. With C# 13, there is now a dedicated Lock type that serves the same purpose. The lock
keyword supports this new type.
// before C# 13
object myLockObject = new();
lock (myLockObject) { ... }
// C# 13
Lock myLockObject = new();
lock (myLockObject) { ... }
More partial options
Before C# 13, only classes or methods could be partial. For WPF developers, this is a common pattern to couple the view and the code behind.
With C# 13, you can now also have partial properties. You can declare them in one partial file and implement them in another one. The compiler is satisfied as long as the signatures match.
partial class A
{
public partial string MyName { get; set; }
}
partial class B
{
private string _myName;
public partial string MyName
{
get => _myName;
set => _myName = value;
}
}
Overload resolution priority
If you have conflicting method overloads and the compiler doesn’t know which one to choose, you can now add the OverloadResolutionPriorityAttribute to the method and specify a value with it. The compiler will then choose the method with the highest value. You can also assign negative values to affect the compiler’s choice.
// preference for method 1
[OverloadResolutionPriority(1)]
public void Method1() { ... }
public void Method2() { ... }
// preference for method 2
[OverloadResolutionPriority(-1)]
public void Method1() { ... }
public void Method2() { ... }
This is mostly targeted at library maintainers so that they can add new overloads to existing code.
Apart from that, there are some other changes but they don’t really tackle me. To get a full in-depth description of every change, read the official documentation about C# 13.
Summary
As I said: The changes are not for the hobby developers. C# is already mature and changing stuff to make it appealing to other people could break things or scare away the developer base. They are doing a good job in my opinion.
C#’s best features you might not be using
This talk looks at some underused C# features that could make you more productive.
Pattern matching
This comes in handy with the switch
keyword. Pattern matching has great compiler support, so you always get helpful hints in case you made an error.
// pattern matching with the switch expression
public bool Nand(bool a, bool b) =>
(a, b) switch
{
(true, true) => false,
_ => true
};
// pattern matching to check a value
public static bool IsNotPerfectSquare(int num)
=> num is not (4 or 9);
// pattern matching null check
object? myObj = CreateObject();
if (myObj is not null)
{
...
}
File scoped namespaces
File scoped namespaces reduce the indentation of your code blocks. You have more horizontal space to work with. Visual Studio offers a quick action so that you don’t have to do it manually.
// Before
namespace MyNamespace
{
public class MyClass
{
}
}
// After
namespace MyNamespace;
public class MyClass
{
}
Init and required
There are two new keywords: init
and required
.
init
is a read-only accessor but the value can be set once with the property initializer syntax.
required
passes the warning of an uninitialized property to the caller if no property initialization is performed.
Here is some code to explain the differences:
public SomeClass1
{
// produces warning because not initialized
public string Name { get; set; }
}
public SomeClass2
{
// no warning at all
public string Name { get; set; } = "xeladu";
}
public SomeClass3
{
// produces warning when instance of SomeClass is created and value is
// not set in the property initializer
public required string Name { get; set; }
}
// valid
var myClass31 = new SomeClass3 { Name = "xeladu" };
// warning
var myClass32 = new SomeClass3();
public SomeClass4
{
// the setter is read-only, but can be set in the property initializer
public string Name { get; init; }
}
// valid
var myClass4 = new SomeClass4 { Name = "xeladu" };
// not possible
myClass4.Name = string.Empty;
String literals
There are many different string constructs that you can handle with C#.
The quoted string
is probably the easiest and most used one. This is useful for logging and debugging, for example.
Console.WriteLine("Some \\"string\\"");
Console.WriteLine("C:\\\\Users\\\\me\\\\Documents\\\\");
Console.WriteLine("Line\\nBreak");
Then, we have verbatim strings
. Here the string is prefixed with an @ sign. The benefit is that you don’t need to escape every single character manually that would require escaping.
Console.WriteLine(@"Some ""string""");
Console.WriteLine(@"C:\\Users\\me\\\\Documents\\");
Console.WriteLine(@"Line
Break");
Next, there are raw strings
. They are especially useful if you are dealing with JSON. No escaping required inside the “””
area!
string json = """
{
"Date": "2024-01-01T:00:00:00-07:00",
"Number": 3,
"Bool": false,
}
""";
And finally, there are also interpolated strings
. They contain a placeholder that is filled with a value. With that way, you don’t need to split the string, add concatenation with +
, and put the value with a ToString()
call inside.
You can even combine all these string types.
var planet = "Earth";
Console.WriteLine($"Hello {planet}");
// prints: Hello Earth
var street = "5th Avenue";
Console.WriteLine($@"The street is name ""{street}""");
// prints: The street is named "5th Avenue"
var user = "me";
Console.WriteLine($@"C:\\Users\\{user}\\Documents\\");
// prints: C:\\Users\\me\\Documents\\
Records
A class
or struct
with an additional record
keyword gets a lot of benefits that you normally would have to write yourself. Examples are implementations of ToString()
, GetHashCode()
, or Equals()
methods.
You also get access to the with
keyword to create a copy of your record where you can set properties.
public record class Customer(
string FirstName,
string LastName,
string? MiddleName = null)
{
}
var x = new Customer("first", "last");
var y = x with { MiddleName = "middle" };
Console.WriteLine(x);
// prints: Customer { FirstName = first, LastName = last, MiddleName = }
Console.WriteLine(y);
// prints: Customer { FirstName = first, LastName = last, MiddleName = middle }
Collection expressions
Collection expressions are a handy feature to declare collections in a shorter way than before.
int[] x1 = [1, 2, 3, 4];
List<int> x2 = [1, 2]
IEnumerable<int> x3 = [];
Summary
Nice overview!
I knew all the tricks already but seeing them again and having them explained in such a good way can be helpful for other developers.
Which of those features were new to you? And which ones do you actually use? 🤔
Tell me in the comments!
🔔 Hint
There is a lot more to discover at .NET Conf! Remember: This is just my personal summary of .NET Conf 2024!
What’s new in WinUI and Windows App SDK 1.6
WinUI and the Windows App SDK offer a way to build native apps with C++ and .NET for the Windows operating system. This is a newer technology than the previous approaches with WinForms or WPF (although both are still supported and under active development).
In the image below you can see what the Windows App SDK includes. WinUI is a part of it although sometimes the terms WinUI and Windows App SDK are used as synonyms.
Improved AOT performance
This essentially means that your apps launches faster and consumes less memory. This is achieved by optimizing the binaries when you build your app. To activate the feature, add the following entry to your .csproj
file:
<PublishAot>true</PublishAot>
The compiler will then tell you what else you need to do (like making some classes partial). That’s it!
TabView tear-out
You maybe know that feature from browser: When dragging a tab out of a window, it will be hosted in a secondary window. The TabView control now also supports this feature. The video offers a walk-through on how to implement this in a few minutes.
PipsPager cycle
What’s the PipsPager you ask? To be honest I had no clue either in the beginning 😃
It’s this control that shows you how many items there are in a collection (like a slideshow). Each item is usually represented by a dot. And the news is that you now jump to the first one when you go forward from the last one.
Customizable RatingControl
The RatingControl is more customizable now because some hard-coded properties were moved to theme resource files.
Summary
The major part of this presentation is explaining the difference between WinUI and Windows App SDK and how good the AOT improvements are (they are great!). Seems like not much happened there. Since I haven’t developed native Windows apps for 4 years (UWP disaster anyone?), I am not in the scene and have no details.
Honest question: Are there people developing Windows native apps with WinUI?
If you prefer reading a blog post instead of watching a video, there you go:
Modern WinForms Development with .NET 9
While probably very few people start with WinForms development projects in these days, there are many existing applications that benefit from modern features.
Here is a short excerpt of what has changed:
- FolderBrowserDialog has a multi-select option
- BinaryFormatter removed
- More overloads for System.Drawing using
Span<T>
to reduce memory allocations - More
async
operations - Dark mode support (but experimental)
Summary
WinForms is mature and stable. However, the multi-select option has been requested for years and according to the presenters, it was not a big task. While I appreciate the changes, the WinForms team could maybe focus more on what the developers really need
Build hybrid apps with .NET MAUI
Hybrid apps are a middle thing between native apps (C#, XAML, .NET MAUI) and web apps (C#, HTML, CSS, Blazor) according to Microsoft. It combines approaches from both worlds to give users a native-like experience for web and mobile apps. A major benefit is that you get access to native platform features and device capabilities while writing your UI with web technologies.
This session is a quick demo of how to create a hybrid app with Visual Studio and a new tailored template for that use case.
In comparison to .NET 8, the setup is now a lot quicker thanks to the template. You get the entire folder structure and projects glued together to get an impression of how web app, native app, and shared libraries work together.
So no matter where you want to deploy to (Windows, iOS, Android, Mac, or Web), you can do that with hybrid apps.
While this works, I really prefer the Flutter approach. The project structure is way simpler and you only need one language (Dart) to write all the code. Hybrid apps typically use C# for the logic and HTML/CSS (or a framework like React or Angular) for the UI.
Improvements with .NET 9
- New Visual Studio template
- Hot reload works better
- You can develop with VS Code since it now has a .NET MAUI extension
- Enhanced documentation
- Many bug fixes
Summary
A good overview for starters. I wouldn’t choose it because HTML/CSS/Javascript are not my preferred tools to work with. If the tech stack is not a problem, it’s worth a look!
API-ly ever after: OpenAPI in .NET 9
Today’s standard in OpenAPI documentation is Swagger. Together with Swashbuckle, you can create a developer-friendly API documentation for ASP.NET web services with ease.
With .NET 9, Microsoft introduces its own solution of OpenAPI documentation. Here are the basic steps to get it working:
- Install the OpenAPI Nuget package
- Add OpenAPI to the web app services with
builder.Services.AddOpenApi()
- Create endpoint for the documentation with
app.MapOpenApi()
- Run the project and navigate to the endpoint with your browser
My first impression is that the UI looks poor. But it’s probably because I am used to seeing the Swagger UI all the time. Endpoints can be grouped, you can send test requests, you see the endpoint documentation, … I am no expert but I don’t see any advantage here.
To document methods and models, you can use annotations or a fluent syntax when using minimal APIs. Compared to Swagger, this solution relies less on annotations. So if you don’t like them, then you have an alternative.
Summary
I haven’t used Swagger a lot but it felt good to me. Was it necessary to put in the effort to replace it with .NET 9? It just feels like when Microsoft decided to implement their own System.Text.JSON
to compete with Newtonsoft.JSON
. I also didn’t understand the reasons at that time.
If someone is more into that topic and can elaborate the reasons or the advantages of this approach, please share them. I currently don’t see a reason why anyone should migrate.
But anyway, more options for developers to choose from!
What’s new in Visual Studio 2022 for .NET developers
There is no Visual Studio 2025, but at least Visual Studio 2022 gets some updates and new features. If you don’t want to watch the video, read the following blog post with a short description of all new and changed functions in Visual Studio 2022 v17.12:
The video presents the following features:
Code search
Trigger it with CTRL + T (ReSharper users have already known this for years). The dialog can search in the solution, in the current project, or in the current document. You get a file preview window and you can even jump to lines in the preview if you add :45
to the query.
Copilot
Copilot now lists files that match your prompt in your solution and it proposes follow-up questions that might be suitable for the user.
In addition, there are now more models supported besides GPT4o. You can select between o1-preview, o1-mini, Gemini 1.5 Pro, and Claude 3.5 Sonnet.
Copilot’s context window was increased and it takes into account more of the current project to reduce wrong answers that don’t compile. It also now understands the latest versions of C# and .NET.
They showed some more use cases where you can use Copilot now. For example to write LINQ queries in the new IEnumerable Visualizer window or to find out why a break point hasn’t been hit.
I tried it a while ago and it was good for basic tasks, but as soon as it gets a bit complicated, the answers were pretty much useless. Let’s see if that improved in this version.
GIT changes
Copilot can now create a commit message for you. In the options of Visual Studio you can give it instructions on how you want the message to be generated.
⚠️ But at the end of the presentation, there was one really cool feature for me. Select a code part, right-click, select Git, then select Copy GitHub perma link, and share it with people. The link will lead them to the corresponding file on GitHub to the exact location of the code selection. Also works for entire files or from the solution explorer. I like this!
Summary
Visual Studio is still the best IDE to develop for .NET in my opinion even if they mostly talked about Copilot… VS Code recently got some better tooling but you still need a bunch of extensions to make it even comparable to Visual Studio. I haven’t tried JetBrains Rider yet, but since I can get it for free now (and you maybe as well?), checking it out is on my agenda.
Disappointing presentation, you should rather read the blog article.
What’s new in the .NET Runtime, Libraries, & SDK
The presentation gives an overview but due to time constraints they can’t go into too much details.
Runtime
- Garbage collector optimizations lead to significantly less memory consumption and higher throughput. Since there are now more calculations involved, the throughput increase might sometimes not be visible.
- The .NET compiler uses heuristics to optimize code when deciding which code branch is more likely to execute.
- Some further compiler optimizations regarding x64 architectures
- Windows apps use hardware protection against Return-Oriented Programming (ROP) attacks by default
Core Libraries
- Save memory in high performance code with spans and GetAlternateLookup on collections
- Failed debug assertion conditions are included in the error
- Index() method to return the index of an enumerable
- Task.WhenEach() to continue execution once a task finishes
- New JsonSchemaExporter type and IntelliSense support in JSON schema files
- BinaryFormatter is insecure and therefore finally removed
SDK
- Nuget package auditing respects transitive dependencies and warns in case of security issues
- CLI output reformatted and with colors no w
- Users can now decided if .NET tools built on older versions of .NET should run on newer version. If your desired tool is built with .NET 6 but you only have .NET 8 installed, pass the flag
--allow-roll-forward
to thedotnet install
ordotnet run
command and it works. dotnet publish
allows publishing to insecure http registries
Summary
A lot of new stuff found its way into .NET 9. The presentations only gives an overview. I recommend to follow the links and check out the details because some interesting stuff hasn’t been mentioned in the video.
Performance improvements in .NET 9
This presentation is roughly 40 minutes long but the full nerd content is available on the .NET blog. The article has about 30,000 words and an estimated reading time of around 150 minutes. If performance is crucial or interesting to you, go and read the deep dive!
I will just highlight some areas of improvement in my summary here:
- GetAlternateLookup to reduce memory consumption of collections (already mentioned in the “What’s new in .NET 9” presentation)
- EnumerateSplits() and
Span<T>
as an alternative to Split() andString
works allocation-free meaning you save a lot of memory in your app when using them with .NET 9 - Improved SearchValues<T> to optimize searching for elements in large lists or files
- Improved TensorPrimitives to support a huge number of new APIs
Summary
It’s always great to see when products get improved.
Do I understand everything what’s happening here? No.
Is it relevant for me? Not really.
But .NET is used by millions of developers which all have different tasks and requirements. It is only natural that not all features are relevant to all parties. In my opinion they are doing a great job!
What’s new in .NET MAUI in .NET 9
After celebrating the growth of the platform and showcasing some apps, the Syncfusion MAUI Toolkit is announced with free and open source controls for .NET MAUI apps. Apart from that you can learn about the following:
- .NET MAUI project template includes sample content with the .NET MAUI Community Toolkit and the Syncfusion MAUI Toolkit
- Syncfusion creates many PRs on the .NET MAUI repository which indicates that they are focused on the platform and will keep supporting it
- .NET MAUI extension for VS Code (IntelliSense, tooltips, hot-reload, …), no need to use Visual Studio anymore
- Native library interop between .NET and other languages like Obj-C, Swift, Kotlin, Java
Summary
Great to see the framework evolve!
I left it roughly 6 months ago because the workloads for Visual Studio just kept disappearing but maybe with the .NET MAUI extension for VS Code I should give it another try. I think that Flutter is the better approach overall but for all people loving C# and targeting mobile, .NET MAUI should be the first choice!
Conclusion
This is my personal summary of .NET Conf 2024. In comparison to previous years I found more talks targeted towards “normal” developers with less AI and cloud. It was interesting, I learned a lot, and I will keep using the .NET platform for my personal projects. It is mature, it is stable, and there is a lot of documentation to get help when needed.