Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
Delegates, Func and Action in C#: Passing Methods Around as Values
A delegate is a type that holds a method: a class deriving from MulticastDelegate, Method and Target, Func/Action/Predicate, the natural type of lambdas in C# 10 and CS8917, passing methods as parameters, the last result of a multicast delegate and the broken chain, converting between delegate types and variance, and the traps of null delegates and lambdas that -= won't remove.
Lambdas and Closures in C#: The Captured Variable Trap
Lambda shapes and the C# 10 explicit return type, a closure capturing the variable rather than its value, seeing the compiler-generated display class with reflection, the captured for loop variable and the C# 5 foreach change, measuring 88 bytes of allocation per closure, static lambdas and CS8820, and the capture bug that meets deferred LINQ.
Events in C#: EventHandler, Safe Raising and Subscription Leaks
How the event keyword protects a delegate and CS0070, the private field and add/remove methods the compiler generates, the EventHandler convention and records as event data, safe raising with ?.Invoke, custom add/remove accessors and CS0079, a 50 MB subscription leak measured with WeakReference, and a Subscribe method that returns IDisposable.
Pattern Matching in C# in Depth: Property, Positional and Tuple Patterns
Property patterns and the C# 10 extended syntax, a match that quietly fails at a null intermediate step, positional patterns with Deconstruct, a decision table with tuple patterns, not/and/or precedence and the is not A or B trap, the var pattern and when, missing and unreachable arms with CS8509, CS8524 and CS8510, and choosing between pattern matching and polymorphism.
Nullable Reference Types in C# in Depth: NotNullWhen, MaybeNull and API Design
Flow analysis stopping at the method boundary and CS8602, a conditional contract with NotNullWhen and CS8762, an unconstrained T? staying plain T for value types, the generic Try pattern with MaybeNullWhen, NotNullIfNotNull, NotNull and AllowNull, MemberNotNull for CS8618, DoesNotReturn, the lack of runtime protection and ThrowIfNull, and #nullable and WarningsAsErrors for a gradual migration.
Attributes and Reflection in C#: Writing and Reading Your Own Attributes
An attribute living in metadata and created when read, Obsolete and CS0618, AttributeUsage, positional and named arguments, decimal not being a valid attribute parameter and CS0181, a small validator with reflection, discovering IDiscountRule types and running them with Activator and Invoke, a BenchmarkDotNet comparison of GetValue, a cached PropertyInfo and a typed delegate, and the limits of trimming and source generators.
Expression Trees in C#: Holding a Lambda as Data, and the Bridge to EF Core
The difference between Func and Expression<Func>, looking at the tree's nodes and Compile, building a dynamic filter with Expression factory methods, a small SQL translator with ExpressionVisitor, IQueryable and EF Core 6's ToQueryString output, a captured variable turning into a parameter, the untranslatable method error, limits such as CS0834, CS8072 and CS8110, and the 70-microsecond cost of Compile measured with BenchmarkDotNet.
Span<T> and Memory<T> in C#: Allocation-Free Parsing, stackalloc and ref struct Rules
Copy-free slicing and allocation-free parsing with Span<T>, a measured allocation difference, stackalloc and its safe pattern, ref struct restrictions, and Memory<T> for async code.
ref Returns, ref Locals, in Parameters and ref struct in C#
Moving values by reference instead of copying them: ref locals, ref returns, ref readonly, the defensive-copy trap with in parameters, readonly structs and writing your own ref struct.
Interop and unsafe Code in C#: P/Invoke, Pointers and fixed
AllowUnsafeBlocks and pointers, pinning against the GC with fixed, calling libc with DllImport, string marshalling, callbacks with function pointers, and keeping unsafe code small with NativeMemory and spans.
Source Generators in C#: Generating Code at Compile Time with IIncrementalGenerator
Writing an incremental generator that adds code during the build: the netstandard2.0 project and Roslyn version, the pipeline and caching, seeing the generated code, and the partial and hint name pitfalls.
Performance in C#: Allocations, Structs and Measuring with BenchmarkDotNet
Why Stopwatch isn't enough, setting up BenchmarkDotNet 0.15.8 and reading its table, the measured difference between classes and structs, hidden allocations from boxing and closures, and benchmark pitfalls.