๐ฆ Using = Resource Management Resources leak without cleanup. Using statements ensure disposal. Files, connections, streams โ auto-cleanup. โ Manual Cleanup var file = File.Open(“file.txt”); try { // Use file } finally { file.Dispose(); } โ Using Statement using var file = File.Open(“file.txt”); // Use file – auto-disposed ๐ Using Examples // File operations using […]
Category: C#
C#: Use Lambda Expressions for Concise Code
โก Lambda Expressions = Concise Code Anonymous methods are verbose. Lambda expressions are concise. One-liners for LINQ, delegates, events. โ Anonymous Method Func square = delegate(int x) { return x * x; }; โ Lambda Expression Func square = x => x * x; ๐ Lambda Examples // Basic syntax (parameters) => expression (parameters) => […]
C#: Use Extension Methods to Add Functionality
๐ Extension Methods = Add Functionality Can’t modify existing types? Extension methods add functionality. Use like instance methods. โ Static Methods string email = “USER@EXAMPLE.com”; email = StringHelper.ToTitleCase(email); โ Extension Method string email = “USER@EXAMPLE.com”; email = email.ToTitleCase(); ๐ Extension Examples // Static class, static methods public static class StringExtensions { public static string ToTitleCase(this […]
C#: Use Generics for Type-Safe Code
๐งฉ Generics = Type-Safe Code Object types are unsafe. Generics create type-safe reusable code. Performance, safety, flexibility. โ Object (Unsafe) public class Stack { private object[] items; public void Push(object item) { } public object Pop() { } } Stack s = new Stack(); s.Push(123); // Boxed int i = (int)s.Pop(); // Cast โ Generic […]
C#: Use Records for Immutable Data Types
๐ Records = Immutable Data Classes are mutable. Records are immutable. Value-based equality, concise syntax, data-centric. โ Class (Mutable) public class Person { public string Name { get; set; } public int Age { get; set; } } โ Record (Immutable) public record Person(string Name, int Age); ๐ Record Features // Positional record public record […]
C#: Use ValueTuples for Multiple Return Values
๐ฆ ValueTuples = Multiple Return Values Returning multiple values is messy. ValueTuples make it clean. Lightweight, named, convenient. โ Out Parameters public void GetUser(out int id, out string name) { id = 1; name = “Alice”; } โ ValueTuple public (int Id, string Name) GetUser() { return (1, “Alice”); } ๐ ValueTuple Examples // Named […]
C#: Struct vs Class โ Choose Wisely
๐ฆ Struct vs Class โ Choose Wisely Both store data. Struct vs Class matters for performance. Value type vs reference type. ๐ Key Differences // Class (Reference Type) public class Person { public string Name { get; set; } public int Age { get; set; } } // Struct (Value Type) public struct Point { […]
C#: Async/Await Best Practices
โก Async/Await Best Practices Async is powerful but tricky. Best practices make it reliable. Performance, deadlocks, error handling. ๐ Best Practices // 1. Use async for I/O only // Good: Database, HTTP, file I/O public async Task GetUserAsync(int id) { … } // Bad: CPU-intensive operations public async Task CalculateAsync(int n) { … } // […]
C#: Use Task-Based Asynchronous Pattern (TAP)
โก TAP = Asynchronous Programming Async is essential. TAP is the standard pattern. Async/await, Task, Task. ๐ TAP Basics // Basic async method public async Task GetDataAsync() { using var client = new HttpClient(); var result = await client.GetStringAsync(“https://api.example.com/data”); return result; } // Async with error handling public async Task GetUserAsync(int id) { try { […]
C#: Master Exception Handling with Try-Catch
๐ก๏ธ Exception Handling = Robust Code Apps crash without error handling. Try-catch handles errors gracefully. Robust, reliable apps. ๐ Try-Catch Basics try { // Code that might throw int result = int.Parse(input); Console.WriteLine($”Result: {result}”); } catch (FormatException ex) { Console.WriteLine($”Invalid format: {ex.Message}”); } catch (OverflowException ex) { Console.WriteLine($”Number too large: {ex.Message}”); } catch (Exception ex) […]
C#: Use String Interpolation for Clean Formatting
๐ String Interpolation = Clean Formatting String concatenation is messy. String interpolation embeds expressions directly. Readable, concise, elegant. โ Concatenation string msg = “Hello, ” + name + “. You are ” + age + ” years old. Today is ” + date.ToShortDateString(); โ Interpolation string msg = $”Hello, {name}. You are {age} years old. […]
C#: Use Null-Coalescing Operator (??) for Default Values
?? Null-Coalescing = Default Values Null checks are verbose. Null-coalescing operator provides defaults. Clean, concise, safe. โ Verbose Null Check string name; if (user != null && user.Name != null) name = user.Name; else name = “Unknown”; โ Null-Coalescing string name = user?.Name ?? “Unknown”; ๐ Null-Coalescing Examples // Null-coalescing (??) string name = user?.Name […]
C#: Use Records for Immutable Data Types
๐ Records = Immutable Data Classes are mutable. Records are immutable. Value-based equality, concise syntax, data-centric. โ Class (Mutable) public class Person { public string Name { get; set; } public int Age { get; set; } } โ Record (Immutable) public record Person(string Name, int Age); ๐ Record Features // Positional record public record […]
C#: Use Indexers for Array-Like Access
๐ Indexers = Array-Like Access Custom collections need array access. Indexers provide array-like syntax. Clean, intuitive, flexible. ๐ Indexer Basics // Simple indexer public class StringCollection { private string[] _items = new string[10]; public string this[int index] { get => _items[index]; set => _items[index] = value; } } // Usage var collection = new StringCollection(); […]
C#: Use ValueTuple for Lightweight Multiple Return Values
๐ฆ ValueTuple = Lightweight Tuples Return multiple values without creating classes. ValueTuple is lightweight, value-based, convenient. ๐ฆ Tuple (Reference Type) var result = Tuple.Create(1, “Alice”); int id = result.Item1; string name = result.Item2; โ ValueTuple (Value Type) var result = (Id: 1, Name: “Alice”); int id = result.Id; string name = result.Name; ๐ฏ ValueTuple Examples […]
C#: Use Object Initializers for Clean Object Creation
๐ฆ Object Initializers = Clean Creation Constructors with many params are messy. Object initializers create objects cleanly. Readable, concise, flexible. โ Constructor public class User { public string Name { get; set; } public int Age { get; set; } public string Email { get; set; } public User(string name, int age, string email) { […]
C#: Use Nullable Reference Types for Null Safety
๐ก๏ธ Nullable Reference Types = Null Safety Null reference is #1 error. Nullable reference types prevent null bugs. Compiler help, fewer crashes, safer code. ๐ Enabling Nullable # Project file enable # Or per file #nullable enable # Disable nullable #nullable disable # Nullable annotations public class Person { // Non-nullable (compiler warns if null) […]
C#: Use Pattern Matching for Elegant Code
๐ฏ Pattern Matching = Elegant Code If-else chains are messy. Pattern matching is elegant. Switch expressions, type matching, property patterns. ๐ Pattern Types // Type pattern if (obj is string s) { Console.WriteLine($”String: {s}”); } else if (obj is int i) { Console.WriteLine($”Integer: {i}”); } // Property pattern if (person is { Name: “Alice”, Age: […]
C#: Use File Scoped Namespaces for Cleaner Code
๐ File Scoped Namespaces = Cleaner Code Namespaces add indentation. File scoped namespaces are cleaner. Less nesting, more readable. โ Old Style namespace MyApp { namespace Models { public class User { } } namespace Services { public class UserService { } } } โ File Scoped namespace MyApp.Models; public class User { } namespace […]
C#: Use Default Interface Methods for API Evolution
๐ Default Interface Methods = API Evolution Interfaces break existing code. Default interface methods add methods without breaking. Evolve APIs safely. ๐ Default Interface Basics // Interface with default method public interface ILogger { void Log(string message); // Default implementation void LogError(string message) { Log($”ERROR: {message}”); } // Default implementation void LogWarning(string message) { Log($”WARNING: […]
C#: Use Native AOT for High-Performance Apps
๐ Native AOT = Ultra Performance JIT compilation has overhead. Native AOT compiles ahead-of-time. Fast startup, low memory, native performance. ๐ AOT Setup # Project file <Project Sdk=”Microsoft.NET.Sdk”> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net8.0</TargetFramework> <PublishAot>true</PublishAot> <TrimMode>full</TrimMode> <EnableAotAnalyzer>true</EnableAotAnalyzer> </PropertyGroup> </Project> # Publish with AOT dotnet publish -c Release -r win-x64 –self-contained # Or dotnet publish -c Release -r linux-x64 […]
C#: Use Source Generators for Code Generation
โก Source Generators = Code Generation Boilerplate code is tedious. Source Generators generate code at compile time. Efficiency, consistency, performance. ๐ Source Generator Setup // Create generator project dotnet new console -n MyGenerator cd MyGenerator dotnet add package Microsoft.CodeAnalysis.CSharp dotnet add package Microsoft.CodeAnalysis.Analyzers // Generator class using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using System.Text; [Generator] […]
C#: Use Span for High-Performance Memory Operations
โก Span = Memory Performance Memory allocations slow down apps. Span provides safe, allocation-free access. High-performance, low-allocation code. ๐ Span Basics // Span from array int[] numbers = {1, 2, 3, 4, 5}; Span span = numbers.AsSpan(); // Slice Span slice = span.Slice(1, 3); // {2, 3, 4} // Modify via span slice[0] = 10; […]
C#: Use Async Streams for Asynchronous Data Sequences
๐ Async Streams = Asynchronous Data Sync streams block. IAsyncEnumerable is async. Process data as it arrives, non-blocking, efficient. ๐ Async Streams Basics // Async stream method async IAsyncEnumerable GenerateNumbersAsync() { for (int i = 0; i < 10; i++) { await Task.Delay(100); // Simulate async work yield return i; } } // Consume async […]
C#: Use Nullable Reference Types for Null Safety
๐ก๏ธ Nullable Reference Types = Null Safety Null reference is #1 error. Nullable reference types prevent null bugs. Compiler help, fewer crashes, safer code. โ Null (Unsafe) public class User { public string Name { get; set; } public string Email { get; set; } } // Potential null reference โ Nullable Reference (Safe) public […]
C#: Use Pattern Matching for Elegant Code
๐ฏ Pattern Matching = Elegant Code If-else chains are messy. Pattern matching is elegant. Switch expressions, type matching, property patterns. โ If-Else Chains if (obj is string) { … } else if (obj is int) { … } else if (obj is bool) { … } โ Pattern Matching switch (obj) { string s => […]
C#: Use Records for Immutable Data Types
๐ Records = Immutable Data Classes are mutable. Records are immutable. Value-based equality, concise syntax, data-centric. โ Class (Mutable) public class Person { public string Name { get; set; } public int Age { get; set; } } โ Record (Immutable) public record Person(string Name, int Age); ๐ Record Features // Positional record public record […]
C#: Use Using Statements for Resource Management
๐ฆ Using = Resource Management Resources leak without cleanup. Using statements ensure disposal. Files, connections, streams โ cleanup automatically. โ Manual Cleanup (Error-Prone) var file = File.Open(“file.txt”); try { // Use file } finally { file.Dispose(); } โ Using Statement (Clean) using var file = File.Open(“file.txt”); // Use file – auto-disposed ๐ Using Examples // […]
C#: Use Lambda Expressions for Concise Code
โก Lambdas = Concise Functions Anonymous methods are verbose. Lambda expressions are concise. One-liners for LINQ, delegates, events. โ Anonymous Method Func square = delegate(int x) { return x * x; }; โ Lambda Expression Func square = x => x * x; ๐ Lambda Syntax // Basic syntax (parameters) => expression (parameters) => { […]
C#: Use Generics for Type-Safe Reusable Code
๐งฉ Generics = Type-Safe Code Object types are unsafe. Generics create type-safe reusable code. Performance, safety, flexibility. โ Object (Unsafe) public class Stack { private object[] items; public void Push(object item) { } public object Pop() { } } Stack s = new Stack(); s.Push(123); // Boxed int i = (int)s.Pop(); // Cast โ Generic […]
