Blog
Mert Özen's blog posts on software development, backend, frontend, and DevOps.
The C# String API in Detail: Searching, Splitting, Joining, Trimming and Replacing
IndexOf, StartsWith and EndsWith with a string argument are culture-sensitive by default, while the char overloads, Contains, Replace and Split are ordinal, so machine data should always get StringComparison.Ordinal. Through Bookstore's slug and ISBN normalization code we show Split options, Join versus +=, AsSpan, SearchValues, CompositeFormat and the .NET 11 Rune overloads, all with real output.
Format Strings in C#: Standard and Custom Number/Date Formats, Alignment and Composite Formatting
A format string turns a value into a string using the culture's rules: N, C, d and D change with the culture, while o, s and InvariantCulture keep machine output fixed. Using Bookstore's invoice line we show standard and custom number and date formats, alignment, taking the currency from the data, N writing three decimals with ICU, and making an Isbn type printable with ISpanFormattable, all with real output.
Globalization in .NET: CultureInfo, CurrentCulture/CurrentUICulture, the Turkish I and ICU on Linux
In .NET, CurrentCulture decides formatting and comparison and CurrentUICulture decides UI text; both flow through async code, and without ICU a container falls into invariant mode. Using Bookstore's catalog sorting and search box we show Turkish sorting, the ı/İ conversion, the culture-dependent dictionary comparer trap, PredefinedCulturesOnly and how tr-TR breaks in chiseled and alpine images, all with real output.
Everyday Work with Numbers: Math, Rounding Modes, Random.Shared, Guid v4/v7 and BigInteger
Math.Round rounds to even by default (2.5 → 2) while decimal formats round away from zero, so for money pass the mode explicitly and round before formatting. Using Bookstore's campaign discount we show MidpointRounding modes, the double-for-money bug and the .NET 11 decimal conversion change, thread safety with Random.Shared, how Guid v7 sorts, and BigInteger, all with real output.
Encoding, Base64, Hex and URIs: UTF-8, BOM, Windows-1254, Base64Url, Uri and URL Encoding
Every crossing between string and bytes needs an agreed encoding: the wrong one silently breaks Turkish letters, a BOM adds an invisible character to a CSV header, and Base64 is not encryption. Using Windows-1254 data from Bookstore's old accounting system and its search links, we show Encoding, CodePagesEncodingProvider, Base64Url, ToHexStringLower, how the URL encoding APIs differ, QueryHelpers and the traps of Uri, all with real output.
Date and Time in Depth: TimeZoneInfo, IANA/Windows Ids, ParseExact, ISO 8601 and Date Arithmetic
Most date and time bugs come from three places: the wrong time zone id, a DateTime parsed with an unclear Kind, and arithmetic that ignores month ends or daylight saving time. Using Bookstore's 5-business-day delivery rule and its Frankfurt warehouse, we show how TimeZoneInfo handles Windows and IANA ids, ParseExact and DateTimeStyles, ISO 8601 round-trips, DateOnly/TimeOnly in JSON and testable date logic with TimeProvider, all with real output.
Environment, Process and Stopwatch: Environment Info, Running External Commands and Measuring Time
Running an external command safely from .NET comes down to three rules: pass arguments with ArgumentList, read stdout and stderr at the same time, and check the exit code and a timeout. Using Bookstore's nightly report tool, we show Environment and RuntimeInformation, environment variables, SpecialFolder and AppContext switches, the deadlock and injection traps of Process, the Process.RunAsync APIs of .NET 11 and measuring time with Stopwatch, all with real output.
Writing Console Apps and CLI Tools: args, System.CommandLine, Exit Codes, Colored Output and the Generic Host
A good CLI tool does not parse args by hand, writes results to stdout and errors to stderr, returns a documented exit code for every case and leaves no half-written file on Ctrl+C. We build Bookstore's bookstore-admin import-prices tool with System.CommandLine 3.0 and show help and tab completion, the exit code contract, cancellation with SIGINT/SIGTERM, NO_COLOR and .NET 11's FORCE_COLOR support, and DI and logging with the Generic Host, all with real output.
Guard Helpers, Equality Helpers and What Arrived in the BCL from .NET 8 to 11
ArgumentNullException.ThrowIfNull and the ArgumentOutOfRangeException helpers of .NET 8 use CallerArgumentExpression to put the parameter name, the value and the rule into the exception in a single line. We convert Bookstore's Order constructor to these helpers and show custom guard methods, the multi-targeting trap, HashCode.Combine and keys that change, choosing StringComparer and EqualityComparer<T>.Create, how Lazy<T> caches exceptions, and a table of the BCL APIs added from .NET 8 to 11.