Stefan Pölz
Clean C# Coder – Test-driven .NET Developer
Vienna, Austria
Actions
Stefan's passion is to practice Clean Code and test-driven development in order to build maintainable high-performance software in an ever-evolving team, supported by tools from the .NET Ecosystem. He loves to attend and speak at public developer events, co-organize local community gatherings, stream live programming sessions, and author open source projects, complementing his expertise in professional software development. As Microsoft MVP (Developer Technologies), JetBrains Community Contributor (.NET) and co-organizer of DotNetDevs.at, it's his ambition to share knowledge about everything C#.
Area of Expertise
Topics
Everything you (don't) want to know about async and await in C#
C#'s Task-based async/await is a quite pervasive asynchronous programming model. Its beauty is encapsulated in syntactic succinctness to utilize hardware resources efficiently while maintaining sequential readability of the code.
The comprising language keywords, compiler features and framework types unlock immense semantic power:
- asynchronous operations and continuations
- error handling
- cooperative cancellation
- progress reporting
- asynchronous disposal
- asynchronous streams
and much more.
The apparent simplicity - in some cases - may conceal the root cause of performance bottlenecks or unexpected behavior. But by gaining a deep understanding of the Async State Machine, which is the core driver of the control flow in asynchronous logic, developers can unveil potential issues with ease. An in-depth expertise of these implementation details enables authors to design reusable libraries and publish responsive applications.
In this code-heavy session, we will demystify the most prevalent aspects of C#'s async and await, as well as related .NET types.
Let none survive! - How to test our unit tests with mutation testing
Executing the very short development cycle of test-driven development requires discipline and practice. However, the .NET ecosystem offers a wide variety of tools that support us in authoring a high-quality suite of unit tests, not only defending production code against defects but also enabling safe refactoring of codebases.
Utilizing the magnificent Stryker.NET, we explore how mutation testing can further improve the effectiveness of C# test suites by testing our unit tests with this technique, and how to continuously integrate it into Pipelines and Workflows. Moreover, we will take a peek under the hood of mutation testing and its possible implementations.
Let's kill some mutants!
Immutability à la C#
Utilizing immutable types - having all their members "pure" - has proven to be an effective technique helping to reason about state, especially in parallel scenarios. Therefore they are heavily used by the .NET Compiler Platform. This reflects in the language being continuously updated with new features to design immutability. The latest additions in C# further expand the toolbox at our fingertips with record types and init-only setters, complementing the good old readonly modifier that entails different semantics depending on its syntactic location.
In this session I would very much like to explore all the different kinds of immutability, and show you how to implement them with the currently available set of keywords, but also inspect available types in .NET, such as the Immutable and Frozen Collections. And, we will reap the benefits of not allowing any (visible) state changes, such as string interning, thread safety, sane singletons, and clearly express intent.
preferred session duration: 60 minutes, including Q&A
demo heavy
Null & Void - Everything about Nothing in .NET
System.NullReferenceException: 'Object reference not set to an instance of an object.'
I used to read this message quite almost every day.
But null references, also referred to as the "billion-dollar mistake" in that context, are also a great mechanism to express optionality and unavailability of a certain resource.
There are great tools to help us deal with ... utilize null pointers.
IDEs and Analyzers have introduced diagnostics which warn us at compile time about potential trouble at runtime.
And recently the magnificent C# 8.0 has brought us nullable reference types: a language feature which lets us annotate our API to clearly communicate the design intent of nullability.
So let's explore nullable reference types (including the accompanying nullable attributes of the BCL), their representation in both Reflection Metadata and the Roslyn API, and complement that with other available keywords and operators based on null. As a side effect, we will learn about the fundamental difference of nullable reference types and nullable value types in .NET. Additionally, we shall discover an alternative to null while still retaining the semantics of "nothing" - Spoiler: the null object pattern.
preferred session duration: 60 minutes, including Q&A
demo heavy
Backing repository: https://github.com/Flash0ver/F0-Talks-NullVoid
Roslyn Source Generators - Never send a human to do a machine's job
.NET Source Generators are the latest metaprogramming technique to add C# code to your compilation.
They help us automate tedious boilerplate implementations of common patterns, replace Reflection-based logic with high-performance strongly typed solutions, and - in some scenarios - enable Native AOT deployments.
Introduced in .NET 5, their capabilities are expanded in .NET 6, which also starts utilizing their power in order to level up well-established scenarios, such as logging, JSON (de)serialization, and regular expressions. Additionally, C# 9.0 adds module initializers and extends partial methods, C# 11 adds file-scoped types, and C# 12 previews Interceptors to further compile-time code generation.
Not only would I like to show you these language features plus the basic mechanics of adding new sources and reporting diagnostics via (Incremental) Source Generators, but also cover a selection of advanced topics, including unit testing (both the Generator itself and the code it generates), code coverage, mutation testing, benchmarking, and how to use nullable reference types within .NET Standard 2.0 Generator-Projects. As a bonus, I shall deliver a suite of (web) tools to kick-start your journey.
TL;DR - C# Source Generators: Would you like to know more?
Technical requirements: Internet access
Target audience: proficient .NET/C# developers
Preferred session duration: 45 - 60 minutes, including Q&A
Let's Code an incremental source generator with Roslyn
(Incremental) source generators allow us to trade in a bit of compile-time for better performance during run-time:
Instead of resorting to general-purpose types and methods, we may utilize auto-generated variants optimized specifically for our user code. With these at our fingertips, we could facilitate high-performance scenarios by, for example, a Reflection-free source. If nothing else, this Roslyn-based metaprogramming relieves authors of writing repetitive patterns over and over again.
While source generators (compatible with the .NET 5 SDK) potentially cause a sluggish developer experience in huge projects and solutions, the programming model of incremental generators (added to the .NET 6 SDK) mitigates that risk.
Come join me in a live coding session and witness the (test-driven) implementation of a fully operational incremental source generator. We will unveil (most of) the intricacies and benefits of incremental source generation along the way. And finally, we shall check the technical quality of the resulting component through benchmarking and mutation testing.
Experience with Roslyn in general or Roslyn 3.8's ISourceGenerator in particular is optional.
Let's Build an incremental source generator with Roslyn
(Incremental) source generators allow us to trade in a bit of compile-time for better performance during run-time: Instead of resorting to general-purpose types and methods, we may utilize auto-generated variants optimized specifically for our user code. With these at our fingertips, we could facilitate high-performance scenarios by, for example, a Reflection-free source. If nothing else, this Roslyn-based metaprogramming relieves authors of writing repetitive patterns over and over again.
Source generators have been available since the .NET 5 SDK. Along with the introduction of incremental generators in the .NET 6 SDK, Microsoft has also started releasing generators and continued to do so with the .NET 7.0 and .NET 8.0 SDKs.
We will try some generators, from both NuGet and out of the box, to understand typical use cases. After examining their implementation to learn more about the programming model, we will build our very own incremental source generator, test-driven of course, and tool-assisted. As finishing touches we shall apply mutation testing and benchmarking before we deem our package almost ready for potential publication.
Experience with .NET/C# in general is required, but experience with Roslyn in particular is optional. An IDE such as Visual Studio (latest) or Rider (latest) is suggested, but using an editor, such as Visual Studio Code (latest C# extension), is also possible. Installation of the .NET 7.0 SDK (latest) is required.
May Roslyn be with you
The .NET Compiler Platform, aka Roslyn, is the compiler for both the C# and the Visual Basic programming language.
This very session analyzes (pun intended) the Compiler APIs that not only expose information about the C# syntax within trees, nodes and tokens, but also offer the semantic model for accessing the compilation and its symbols. Additionally, we will utilize the APIs for Diagnostics and Workspaces, which serve as extension points for custom components:
- Diagnostic Analyzers: report diagnostics, such as warnings, that show up in CLI builds and as "squigglies" in your editor
- Diagnostic Suppressors: programmatically suppress non-error diagnostics
- Code Fixers: register "light bulb" code actions to fix diagnostics via `Ctrl+.` or `Alt+Enter`
- Code Refactorings: register diagnostic agnostic code actions
- (Incremental) Source Generators: emit additional C#/VB code and Interceptors to your compilation
But wait, there's more! Unit testing, benchmarking, generating NuGet packages and Visual Studio extensions, and using nullable reference types within .NET Standard 2.0 compatible Roslyn projects.
As a bonus, I shall deliver a suite of (web) tools to kick-start your journey.
May the .NET Compiler Platform be with you.
C# 11 + .NET 7 = Generic Math
Although we are capable of overloading operators for owned types with traditional C#, we cannot define generic mathematical algorithms that may be consumed by multiple types of the .NET ecosystem.
Previewed in .NET 6, November 2022 marked the release of Generic Math in .NET 7. New language features of C# 11 enable both Microsoft's BCL team and the community to ship powerful mathematical operations in data types and generic interfaces. These result in algorithms that supersede repetitive concepts, such as System.Math and System.MathF.
Alongside exploring these additions to .NET, we'll assemble our own custom type with calculations that utilizes Generic Math.
More Roslyn Source Generators
Since their inception in .NET 5, Roslyn Source Generators have become more and more prevalent to our projects, and have proven to be integral to a productive development workflow. Not only do they automate maintaining repetitive boilerplate code and help to avoid Reflection for faster and trim-friendlier apps, but also replace dynamic code to enable Native AOT scenarios.
Every major version of the SDK has expanded the capabilities of Generators, and .NET 8 makes no difference by adding a preview of Interceptors in C# 12. The 2023's release, just as every release since .NET 6, also ships new and improved Generators like the Configuration-Binding and COM interop Generators. Apart from that, we explore established Generators by example, both from the BCL and popular packages, and you learn how to write, test, debug, and deploy these yourself. We also delve into advanced topics, such as performance considerations and designing proper incremental generators.
Would you like to know more about Roslyn Source Generators?
Experimental C# Interceptors: AOT & Performance for free
The just-in-time compiler (JIT) is a mighty beast of the .NET runtime. And it becomes more powerful with every release of .NET. But it comes along with a cost during run-time, when compiling the assemblies containing intermediate language code into machine code. A price we may not pay gladly for highly scalable cloud services. Native AOT, compiling deployments ahead-of-time into executable code, moves this complexity to compile-time. But features that utilize dynamic code emission may stop working.
C# 12.0 - shipped with .NET 8.0 - brings us a new experimental language feature: Interceptors. An interceptor is basically the inverse of a goto statement that enables the Roslyn compiler to replace reflection-based call sites with specialized implementations. Combined with (incremental) source generators, codebases become more trimmable, more Native AOT-friendly and can unlock better performance.
Let's inspect this new concept in detail and see it in action.
The ins and outs of ref in C#
Over the past two decades, passing arguments by reference has come a long way in C#. With modern versions of the language, we not only have "ref" and "out" at our disposal, but also "in", "scoped ref" and "ref readonly". But wait, there's more! ByRef returns, local by-reference variables, and ref structs with ref fields, including the upcoming generic anti-constraint for ByRef-like types.
All these variations of references are used more and more in the Base Class Library and NuGet packages from the .NET ecosystem, for example, by the mighty type "Span" and its related memory APIs. It's high time to learn the differences and applications of all of these keywords to unlock correctness and high-performance for our .NET apps and libraries.
Idiomatic C# - The best practices for .NET
Over the past 2 decades, C# has grown into a powerful programming language. But with great power comes great responsibility.
When designing public APIs, library authors consider best practices to meet the consumers' expectations when publishing dependencies to the public NuGet.org or internal feeds. For example when disposing objects, validating arguments in asynchronous methods, or designing Try-Methods correctly that utilize buffers, and other conventions.
This session unveils the most prevalent idioms and patterns of C#.
Of (incremental) Generators and (experimental) Interceptors
Would you like to know how incremental source generation and (currently experimental) interception grant you AOT & performance "for free"?
Since their inception in .NET 5, Source Generators of the .NET Compiler Platform are becoming more and more prevalent in our projects. Especially the upgraded .NET 6 Incremental Generators have proven to be integral to a productive development workflow. Not only do they automate maintaining repetitive boilerplate code and help to avoid Reflection for faster and trim-friendlier apps, but they also replace dynamic code to enable Native AOT scenarios.
Every major version of the SDK has expanded the capabilities of Roslyn Source Generators. .NET 8 makes no difference by adding a preview of Interceptors with the C# 12 compiler as an experimental feature, that has received improvements in the latest .NET 9 already. These allow you to reroute existing call sites to a specialized method at compile-time.
May Roslyn be with you!
Would you like a Slice of Span<>?
Slicing services consciously has become the Zeitgeist of modern software architecture. But are you slicing equally well into your memory?
Both Span and ReadOnlySpan have become the most prevalent abstractions over contiguous memory in .NET (i.e. heap arrays, stackalloc blocks and native memory). Just like the good old ArraySegment, these two allow allocation-free sub-views into such memory regions while generalizing high-performance algorithms. But with great power comes great responsibility, so the Compiler enforces strict lifetime checks. Some of which are partially lifted with C# 13, but most remain by design for these ref structs. Understanding these restrictions is vital to enabling non-breaking adoption of this 16-bytes-sized powerhouse.
Since their inception in 2018, the C# language is more and more alleviating Span (and other ref structs), as well as the BCL of the yearly .NET releases is increasingly embracing its usage in both implementation details and the public surface area. High time to learn all about Span via these slices of knowledge:
- ref structs, ref (readonly) fields, ref (readonly) locals, ref (readonly) returns
- anatomy of Span and ReadOnlySpan
- Collection Expressions and params Collections
- slicing Syntax and Semantics
- allocation-free usage patterns and related high-performance Memory-APIs, including Memory, ReadOnlyMemory and IMemoryOwner
- usage of (ReadOnly)Span in the BCL and Libraries of the Ecosystem
- Scope Checks, scoped keyword and UnscopedRef-Attribute and the brand new allows ref struct generic anti-constraint
- dangerous operations via Unsafe and MemoryMarshal
My challenge is to make you an Aficionado of this ByRef-like type and a Connoisseur of all related Memory APIs. This code-heavy session will train your eye to detect potential utilization of Span and friends in your Libraries and Applications, to unlock measurable performance gains that make your code best friends with the Runtime and the GC.
So let's have our (slice of) cake and eat it, too!
For a shorter abstract on the website, feel free to remove the paragraph that lists the items of the agenda.
Clean C# Code & Test-driven .NET development
Clean Code and Test-driven development (TDD) are well established and quite widespread. If applied thoughtfully, these practices help us to author maintainable and robust software.
In this session, we'll inspect general paradigms of Clean Code and discuss the most prevalent idioms of the C# programming language, from features both old and new. You will learn, how these patterns work well in conjunction with the convention of TDD and how they complement, and in some cases, even enable each other. Moreover, I'll showcase powerful tools from the .NET ecosystem that support this harmonic duo and assist in authoring composable modules with concise control- and data-flows within clear boundaries.
Although a single session can't provide a complete and definitive guide, it should ignite ideas and spawn conversations which rules to adopt, alter or drop. We're focusing on a subset of guidelines that empower us to make conscious design and implementation decisions for durable source code. My goal is that you walk out with a heightened sense of how to develop a C# codebase that's just fun to work with and avoids the stigma of legacy code.
C#shenanigans
Let's break some expectations of .NET!
.NET offers an incredibly powerful development platform. Equally powerful is the C# language. Both are packed with over two decades of features. But with great power comes great responsibility. Plenty of basic principles are put in place that come encoded in well-known coding conventions. What could happen if we were to break these rules? Could we measurably impact performance? Could we even cause unexpected behavior?
In this session, we're going to subvert expectations. Can you figure out what we did behind the scenes? Can you uncover our sly little secrets? Through this rather unconventional approach to teaching, you will gain deeper insights into the semantics of the C# language and the internals of the .NET Runtime. Additionally, you shall learn the origin of certain guidelines and best practices as well as how established coding patterns and diagnostic analyzers are steering you towards the pit of success.
It's time to break bad with C#!
Pattern-based C#: if it quacks like a duck…
C# is a strongly typed programming language, to communicate expectations in a statically verifiable fashion across the .NET ecosystem. For example features such as LINQ require the type-in-use to implement a certain interface (e.g., the generic IEnumerable interface). Well, there is the dynamic keyword, but this is used quite rarely because it circumvents the type safety and has a measurable performance impact.
However, there is a set of features that the compiler allows you to safely enable on types by satisfying a particular shape, rather than through inheritance and implementation.
Features like:
- use any type within foreach statements
- apply the await operator to any type
- tuple-like deconstruction of internal and external types
- implicit Index and Range support
- collection initializers and expressions for user-defined types
and more.
Join our live coding session for a deep dive into the patterns recognized by the Roslyn compiler to learn how to augment reusable types for most convenient and idiomatic consumption in libraries and applications alike.
If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.
NDC London 2025 Sessionize Event Upcoming
Update Conference Prague 2024 Sessionize Event
Techorama 2024 Netherlands Sessionize Event
.NET DeveloperDays 2024 Berlin Sessionize Event
ABP Dotnet Conference 2024 Sessionize Event
Coding Club Presents:
Project: FlashOWare.Generators
Repository: https://github.com/FlashOWare/FlashOWare.Generators
Meetup: https://www.meetup.com/coding-club-vienna/
Swetugg Stockholm 2024 Sessionize Event
[HYBRID] Lightning Talks Evening!
Lightning talk: An Ode to Roslyn Source Generators
User Group Meetup: .NET Notts
https://www.meetup.com/dotnetnotts/
Repository: https://github.com/Flash0ver/F0-Talks-SourceGenerators
.NET Conf 2023 Sessionize Event
BASTA! Mainz 2023
Talk: Metaprogrammierung mit Roslyn
Venue page: https://basta.net/mainz/location-mainz/
Session page: https://basta.net/net-framework-c/metaprogrammierung-roslyn/
Speaker page: https://basta.net/speaker/stefan-poelz/
Demo repository: https://github.com/Flash0ver/F0-Talks-Roslyn
WUG Days 2023.2
Speaker page: https://wug.cz/prednasejici/322-Stefan-Polz
Session 1: May Roslyn be with you
Details: https://wug.cz/brno/akce/1600-May-Roslyn-be-with-you
Repo: https://github.com/Flash0ver/F0-Talks-Roslyn
Session 2: Let's Code an incremental source generator with Roslyn
Details: https://wug.cz/brno/akce/1608-Let-s-Code-an-incremental-source-generator-with-Roslyn
Repo: https://github.com/Flash0ver/F0-Talks-SourceGenerators
NDC Oslo 2023 Sessionize Event
JetBrains .NET Webinar
A JetBrains .NET Webinar
Event Page: https://blog.jetbrains.com/dotnet/2023/05/05/stefan-polz-how-to-test-csharp-unit-tests-with-mutation-testing-webinar-recording/
Recording: https://www.youtube.com/live/9BoKyeZapLs
Repository: https://github.com/Flash0ver/F0-Talks-MutationTesting
Warsaw IT Days 2023
The sweet Syntax of C# 11
as VoD
Repository: https://github.com/Flash0ver/F0-Talks-CSharp
NDC London 2023 Sessionize Event
Festive Tech Calendar 2022 Sessionize Event
Update Conference Prague 2022 Sessionize Event
JetBrains .NET Days Online 2022 Sessionize Event
.NET User Group Zürich
Never send a human to do a machine's job
Video: https://www.youtube.com/watch?v=eruy7GffDPM
Repository: https://github.com/Flash0ver/F0-Talks-SourceGenerators
Dotnetos Conference 2022
online three-day conference
Talk: Roslyn Source Generators - Never send a human to do a machine's job
Recording: https://www.youtube.com/watch?v=DKp2ACeB06k
Organizer: https://dotnetos.org/
DotNetDevs.at - Lightning Talks by You!
recurring Meetup organized by DotNetDevs.at
Talk: Let none survive! - How to test our unit tests with mutation testing
Recording: https://www.youtube.com/watch?v=upw9AOrKZH8&t=1956s
Organizer: https://dotnetdevs.at
Developer Week '22 Sessionize Event
NDC London 2022 Sessionize Event
PostSharp Live Webinar
Webinar series organized by PostSharp
Talk: Roslyn Source Generators - Never send a human to do a machine's job
Recording: https://blog.postsharp.net/post/webinar-source-generators
Organizer: https://www.postsharp.net/
.NET Oxford Lightning Talks Sessionize Event
dotnetsheff - January 2022 Meetup
recurring Meetup organized by dotnetsheff
Talk: Null & Void - Everything about Nothing in .NET
Recording: https://www.youtube.com/watch?v=SSEp_JgAt1E
Organizer: https://dotnetsheff.co.uk/
December 2021 Meetup
online Meetup organized by .NET South West
Talk: Null & Void - Everything about Nothing in .NET
Recording: n/a
Organizer: https://www.meetup.com/dotnetsouthwest/
Dot Net North - December 2021 Meetup
recurring Meetup organized by Dot Net North
Talk: Null & Void - Everything about Nothing in .NET
Recording: https://www.youtube.com/watch?v=V08poPZTYwI
Organizer: https://dotnetnorth.org.uk/
NDC Oslo 2021 Sessionize Event
[Online] Lightning Talks!
recurring Meetup organized by dotnetsheff
Talk: Let none survive! - How to test our unit tests with mutation testing
Recording: https://www.youtube.com/watch?v=ZdZJKp12hPI
Organizer: https://dotnetsheff.co.uk/
DotNetDevs.at - July 2021 Meetup
recurring Meetup organized by DotNetDevs.at
Talk: Null & Void - Everything about Nothing in .NET
Recording: https://www.youtube.com/watch?v=pXTxSwNgukk
Organizer: https://dotnetdevs.at
Thunderstorm Talks
recurring Meetup organized by .NET Oxford
Talk: Let none survive! - How to test our unit tests with mutation testing
Recording: https://www.youtube.com/watch?v=bQ6ThS_uglY
Organizer: https://www.dotnetoxford.com/
The Unhandled Exception Podcast - Episode 18
Software Development podcast hosted by Dan Clarke
Show: Episode 18: Mutation Testing in .NET with Stefan Pölz
Podcasts: https://unhandledexceptionpodcast.com/posts/0018-mutationtesting/
Host: https://unhandledexceptionpodcast.com
[Online] Lightning Talks!
recurring Meetup organized by .NET Notts
Talk: Let none survive! - How to test our unit tests with mutation testing
Recording: n/a
Organizer: https://dotnetnotts.co.uk/
JetBrains .NET Days Online 2021 Sessionize Event
Virtual - Lightning Talks
online Meetup organized by .NET South West
Talk: How to test our unit tests with mutation testing
Recording: https://www.youtube.com/watch?v=zbOnygEeFLU&list=PL-qmyXuxfTUFpWZdna_0_2ItFfGtlSAQ_&index=5
Organizer: https://www.meetup.com/dotnetsouthwest/
DotNetDevs.at - November 2019 Meetup
recurring Meetup organized by DotNetDevs.at
Talk: Everything you (don't) want to know about async/await
Recording: https://www.youtube.com/watch?v=flGlypydA8c
Organizer: https://dotnetdevs.at
Please note that Sessionize is not responsible for the accuracy or validity of the data provided by speakers. If you suspect this profile to be fake or spam, please let us know.
Jump to top