🚀 C# Introduction
🎯 Complete Definition
C# (pronounced "C Sharp") is a modern, object-oriented, and type-safe programming language developed by Microsoft as part of its .NET initiative. Created by Anders Hejlsberg and released in 2000, C# combines the power of C++ with the simplicity of Visual Basic. It's designed for building a wide range of applications that run on the .NET platform.
🔬 Core Characteristics
- Object-Oriented: Encapsulation, inheritance, polymorphism with classes and interfaces.
- Type-Safe: Static typing with type inference, nullable reference types, compile-time checks.
- Component-Oriented: Properties, events, delegates, and attributes.
- Garbage Collected: Automatic memory management.
- Cross-Platform: .NET Core/.NET 5+ runs on Windows, Linux, macOS.
- Functional Features: LINQ, lambda expressions, pattern matching, records.
- Async Programming: Built-in async/await model.
📊 Industry Usage
C# is a top-5 language used by millions for enterprise applications, game development (Unity), web backends (ASP.NET), mobile apps (Xamarin/MAUI), and cloud services (Azure). Major companies like Stack Overflow, GoDaddy, and Dell rely on C#.
using System;
namespace CodeOrbitPro
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("🎯 C# 12 - CodeOrbitPro Pro Track");
string language = "C#";
int year = 2000;
Console.WriteLine($"Hello, {language}! Created in {year}.");
}
}
}
📊 Basics & Syntax
🎯 Complete Definition
C# syntax is C-style with semicolons, curly braces, and case-sensitivity. Programs consist of namespaces, classes, and methods with a Main entry point.
📋 Key Elements
- Namespaces: Organize code, prevent naming conflicts
- Classes: Blueprint for objects
- Main Method: Entry point: static void Main(string[] args)
- Statements: End with semicolon ;
- Variables: Declared with type or var (inferred)
- Comments: // single-line, /* */ multi-line, /// XML doc
- Console I/O: Console.WriteLine(), Console.ReadLine()
using System;
namespace Basics
{
class Program
{
static void Main()
{
// Single-line comment
/* Multi-line
comment */
/// XML documentation
Console.Write("Enter name: ");
string name = Console.ReadLine();
var age = 25; // type inference
Console.WriteLine($"Hello, {name}! Age: {age}");
}
}
}
📦 Data Types
🎯 Complete Definition
C# data types are divided into value types (stack) and reference types (heap). Value types include primitives, structs, enums. Reference types include classes, interfaces, delegates, arrays, strings.
📊 Type Categories
- Value Types: int, double, bool, char, decimal, struct, enum
- Reference Types: string, object, class, interface, delegate, array
- Nullable Types: int? (allows null for value types)
- Type Inference: var (compile-time)
- Dynamic: dynamic (runtime typing)
📏 Numeric Types
- Integers: byte, sbyte, short, ushort, int, uint, long, ulong
- Floating: float (32-bit), double (64-bit), decimal (128-bit high precision)
using System;
class Program
{
static void Main()
{
// Value types
int age = 30;
double price = 19.99;
decimal salary = 5000.50m; // m suffix
bool isActive = true;
char grade = 'A';
// Reference types
string name = "C# Programming";
object obj = 42; // boxing
// Nullable
int? maybeNumber = null;
// Type checking
Console.WriteLine(name.GetType()); // System.String
Console.WriteLine(typeof(int)); // System.Int32
// Default values
int defaultInt = default; // 0
string defaultString = default; // null
}
}
🔢 Operators
🎯 Complete Definition
Operators perform operations on operands. C# supports arithmetic, relational, logical, bitwise, assignment, and special operators with specific precedence.
🔧 Operator Categories
- Arithmetic: + - * / % ++ --
- Relational: == != < > <= >=
- Logical: && || !
- Bitwise: & | ^ ~ << >>
- Assignment: = += -= *= /= %= <<= >>= &= |= ^=
- Null-conditional: ?. (member access), ?[] (index)
- Null-coalescing: ?? (if null), ??= (assign if null)
- Ternary: condition ? trueExpr : falseExpr
using System;
class Program
{
static void Main()
{
int a = 10, b = 3;
// Arithmetic
Console.WriteLine(a + b); // 13
Console.WriteLine(a / b); // 3 (integer division)
Console.WriteLine(a % b); // 1
// Null operators
string str = null;
int? length = str?.Length; // null (safe)
string name = str ?? "Default"; // "Default"
str ??= "Assigned"; // assigns if null
// Ternary
string result = a > b ? "greater" : "less";
// Bitwise
int flags = 0b1010;
flags |= 0b0100; // 0b1110
}
}
🔀 Control Flow
🎯 Complete Definition
Control flow statements determine execution path: conditional branching, loops, and jumps. C# supports modern pattern matching in if and switch.
🔄 Flow Structures
- if/else if/else: Conditional branching
- switch: Multi-way branch with pattern matching
- for: Counter-based loop
- foreach: Iterates over IEnumerable collections
- while/do-while: Condition-based loops
- Pattern matching: if (obj is string s) { }
- break/continue/return/goto: Jump statements
using System;
class Program
{
static void Main()
{
int score = 85;
// if-else
if (score >= 90) Console.WriteLine("A");
else if (score >= 80) Console.WriteLine("B");
else Console.WriteLine("C");
// switch with patterns
object obj = 42;
switch (obj)
{
case int i when i > 0:
Console.WriteLine($"Positive int: {i}");
break;
case string s:
Console.WriteLine($"String: {s}");
break;
default:
Console.WriteLine("Unknown");
break;
}
// for loop
for (int i = 0; i < 3; i++)
Console.WriteLine(i);
// foreach
int[] numbers = { 1, 2, 3 };
foreach (var num in numbers)
Console.WriteLine(num);
}
}
📋 Arrays & Collections
🎯 Complete Definition
Arrays are fixed-size, zero-indexed sequences. Collections from System.Collections.Generic provide dynamic sizing and type safety with List, Dictionary, HashSet, Queue, Stack.
📚 Collection Types
- Array: int[] arr = new int[5]; or int[] arr = {1,2,3};
- List<T>: Dynamic array with Add, Remove, Insert, Sort
- Dictionary<K,V>: Key-value pairs with fast lookup
- HashSet<T>: Unique values with set operations
- Queue<T>: FIFO with Enqueue/Dequeue
- Stack<T>: LIFO with Push/Pop
- LinkedList<T>: Doubly-linked list
- SortedDictionary/SortedList: Sorted key-value
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
// Array
int[] numbers = { 1, 2, 3, 4, 5 };
Console.WriteLine(numbers[2]); // 3
// List
List<string> fruits = new List<string> { "apple", "banana" };
fruits.Add("orange");
fruits.Remove("banana");
// Dictionary
Dictionary<string, int> scores = new()
{
["Alice"] = 95,
["Bob"] = 87
};
scores["Charlie"] = 92;
// HashSet
HashSet<int> unique = new HashSet<int> { 1, 2, 3, 1 };
unique.Add(4);
Console.WriteLine(unique.Count); // 4
// Queue
Queue<string> queue = new();
queue.Enqueue("first");
queue.Enqueue("second");
Console.WriteLine(queue.Dequeue()); // first
// Stack
Stack<int> stack = new();
stack.Push(10);
stack.Push(20);
Console.WriteLine(stack.Pop()); // 20
}
}
⚙️ Methods
🎯 Complete Definition
Methods encapsulate reusable code with parameters and return values. C# supports overloading, optional parameters, named arguments, ref/out/in parameters, expression-bodied members, and local functions.
⚙️ Method Features
- Parameters: Pass by value (default), ref (by reference), out (multiple returns), in (read-only ref)
- Optional parameters: Default values provided
- Named arguments: Specify by name: method(age:30, name:"John")
- Expression-bodied: int Square(int x) => x * x;
- Local functions: Methods inside methods
- Extension methods: Add methods to existing types
using System;
class Program
{
// Regular method
static int Add(int a, int b) => a + b;
// Out parameter
static bool TryParse(string input, out int result)
=> int.TryParse(input, out result);
// Optional and named parameters
static void Greet(string name, string title = "Mr.")
=> Console.WriteLine($"Hello, {title} {name}");
// Ref parameter
static void Double(ref int x) => x *= 2;
// Local function
static int Fibonacci(int n)
{
int Fib(int a, int b, int count) => count == 0 ? a : Fib(b, a + b, count - 1);
return Fib(0, 1, n);
}
static void Main()
{
Console.WriteLine(Add(5, 3)); // 8
if (TryParse("123", out int val))
Console.WriteLine(val);
Greet("Smith"); // Hello, Mr. Smith
Greet(title: "Ms.", name: "Jane"); // Named arguments
int num = 5;
Double(ref num);
Console.WriteLine(num); // 10
Console.WriteLine(Fibonacci(10)); // 55
}
}
🏗️ Classes & OOP
🎯 Complete Definition
Classes are reference types that encapsulate data (fields) and behavior (methods, properties). OOP principles: encapsulation, inheritance, polymorphism. Access modifiers control visibility.
🏛️ Class Members
- Fields: Member variables
- Properties: public int Age { get; set; } (auto-implemented or with logic)
- Constructors: Initialize objects, can be overloaded, chained with this()
- Methods: Member functions
- Static members: Belong to class, not instances
- Readonly fields: Set only in constructor
- Constants: const (compile-time)
- Indexers: Allow object[index] syntax
using System;
public class Person
{
// Fields
private string _name;
private int _age;
// Auto-property
public string City { get; set; }
// Readonly field
public readonly DateTime CreatedAt;
// Properties with logic
public string Name
{
get => _name;
set => _name = value ?? "Unknown";
}
public int Age
{
get => _age;
set => _age = value >= 0 ? value : 0;
}
// Constructor
public Person(string name, int age)
{
Name = name;
Age = age;
CreatedAt = DateTime.Now;
}
// Constructor chaining
public Person(string name) : this(name, 0) { }
// Method
public virtual void Introduce()
=> Console.WriteLine($"Hi, I'm {Name}, {Age}");
// Static method
public static Person CreateAnonymous() => new("Anonymous", 0);
}
class Program
{
static void Main()
{
var alice = new Person("Alice", 30) { City = "New York" };
alice.Introduce();
var anon = Person.CreateAnonymous();
anon.Introduce();
}
}
🔗 Inheritance
🎯 Complete Definition
Inheritance allows a class to derive from a base class, inheriting members. C# supports single inheritance (one base class). Polymorphism enables derived classes to override virtual/abstract members.
🔗 Key Concepts
- Base class: class Animal { public virtual void Speak() { } }
- Derived class: class Dog : Animal { public override void Speak() { ... } }
- Abstract class: abstract class Shape { public abstract double Area(); }
- Sealed class: sealed class FinalClass - cannot be inherited
- base keyword: Access base class members
- new keyword: Hide base member (non-polymorphic)
- virtual/override: Enable polymorphic behavior
using System;
public abstract class Shape
{
public abstract double Area();
public virtual void Display() => Console.WriteLine("Shape");
}
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius) => Radius = radius;
public override double Area() => Math.PI * Radius * Radius;
public override void Display() => Console.WriteLine($"Circle radius {Radius}");
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public override double Area() => Width * Height;
}
class Program
{
static void Main()
{
Shape[] shapes = { new Circle(5), new Rectangle(4, 6) };
foreach (var shape in shapes)
{
shape.Display();
Console.WriteLine($"Area: {shape.Area():F2}");
}
}
}
📐 Interfaces
🎯 Complete Definition
Interfaces define contracts that classes implement. They contain method, property, event, or indexer signatures without implementation (C# 8+ allows default implementations). A class can implement multiple interfaces.
📐 Interface Features
- Declaration: interface IComparable { int CompareTo(object obj); }
- Implementation: class MyClass : IInterface1, IInterface2
- Default methods (C# 8): Provide implementation in interface
- Explicit implementation: Resolve naming conflicts
- IEnumerable/IEnumerator: For foreach iteration
- IDisposable: For resource cleanup
- IComparable/IComparer: For sorting
using System;
using System.Collections;
public interface ILogger
{
void Log(string message);
// Default implementation (C# 8+)
public void LogError(string error) => Log($"ERROR: {error}");
}
public interface IMetrics
{
void RecordMetric(string name, double value);
}
// Multiple interface implementation
public class FileLogger : ILogger, IMetrics, IDisposable
{
public void Log(string message)
=> Console.WriteLine($"File: {message}");
public void RecordMetric(string name, double value)
=> Console.WriteLine($"Metric {name} = {value}");
public void Dispose()
=> Console.WriteLine("Logger disposed");
}
// IEnumerable example
public class NumberCollection : IEnumerable
{
private int[] numbers = { 1, 2, 3, 4, 5 };
public IEnumerator GetEnumerator() => numbers.GetEnumerator();
}
class Program
{
static void Main()
{
ILogger logger = new FileLogger();
logger.Log("Information");
logger.LogError("Something went wrong");
// Using IDisposable
using (var log = new FileLogger())
{
log.Log("In using block");
}
// IEnumerable enables foreach
foreach (int num in new NumberCollection())
Console.WriteLine(num);
}
}
📦 Generics
🎯 Complete Definition
Generics allow classes, methods, and interfaces to be parameterized by type, providing type safety without performance cost. Generic collections (List<T>) are widely used. Constraints restrict type parameters.
🔧 Generic Features
- Generic class: class Box<T> { public T Content { get; set; } }
- Generic method: T Max<T>(T a, T b) where T : IComparable<T>
- Constraints: where T : class (reference), struct (value), new() (constructor), base class, interface
- Covariance (out): IEnumerable<out T>
- Contravariance (in): IComparer<in T>
- Generic delegates: Func<T>, Action<T>, Predicate<T>
using System;
using System.Collections.Generic;
// Generic class
public class Repository<T>
{
private List<T> _items = new();
public void Add(T item) => _items.Add(item);
public T Get(int index) => _items[index];
public int Count => _items.Count;
}
// Generic method with constraints
public class Utilities
{
public static T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) > 0 ? a : b;
public static T CreateInstance<T>() where T : new()
=> new T();
}
// Covariance example
public interface IProducer<out T> { T Produce(); }
public class StringProducer : IProducer<string>
{
public string Produce() => "Hello";
}
// Generic delegates
public delegate T Transformer<T>(T input);
class Program
{
static void Main()
{
var intRepo = new Repository<int>();
intRepo.Add(10);
intRepo.Add(20);
Console.WriteLine(intRepo.Get(1)); // 20
Console.WriteLine(Utilities.Max(5, 10)); // 10
Console.WriteLine(Utilities.Max("apple", "banana")); // banana
// Covariance
IProducer<string> stringProducer = new StringProducer();
IProducer<object> objectProducer = stringProducer; // OK
// Generic delegate
Transformer<int> square = x => x * x;
Console.WriteLine(square(5)); // 25
}
}
🔍 LINQ - Language Integrated Query
🎯 Complete Definition
LINQ (Language Integrated Query) is a set of features introduced in C# 3.0 that allows writing declarative queries against various data sources directly in C#. It provides both query syntax (SQL-like) and method syntax (extension methods) with deferred execution. LINQ is built on IEnumerable<T> and IQueryable<T> interfaces.
📋 LINQ Syntax Types
- Query Syntax:
from n in numbers where n % 2 == 0 select n (SQL-like)
- Method Syntax (Fluent):
numbers.Where(n => n % 2 == 0).Select(n => n)
- Mixed Syntax: Can combine both approaches
🔧 Standard Query Operators (50+ methods)
Filtering & Projection
- Where: Filters sequence based on predicate
- OfType: Filters by type
- Select: Projects each element into new form
- SelectMany: Projects and flattens sequences
Ordering
- OrderBy / OrderByDescending: Sorts ascending/descending
- ThenBy / ThenByDescending: Secondary sorting
- Reverse: Reverses order
Aggregation
- Sum, Average, Min, Max, Count, LongCount
- Aggregate: Applies accumulator function
Set Operations
- Distinct: Removes duplicates
- Union, Intersect, Except: Set operations
- Concat: Concatenates sequences
Grouping & Joining
- GroupBy: Groups elements by key
- Join: Inner join of two sequences
- GroupJoin: Grouped join
- Zip: Combines two sequences pairwise
Quantifiers & Element Operators
- Any, All, Contains: Check conditions
- First / FirstOrDefault, Last / LastOrDefault
- Single / SingleOrDefault, ElementAt / ElementAtOrDefault
Partitioning & Generation
- Take / TakeWhile: Takes first N elements
- Skip / SkipWhile: Skips first N elements
- Range, Repeat, Empty: Generates sequences
Conversion
- ToList, ToArray, ToDictionary, ToLookup
- Cast, AsEnumerable, AsQueryable
⚡ Execution Types
- Deferred Execution: Query executes when iterated (Where, Select)
- Immediate Execution: Returns value immediately (Sum, ToList, Count)
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
static void Main()
{
// Sample data
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
var people = new List<Person>
{
new Person { Name = "Alice", Age = 30, City = "New York" },
new Person { Name = "Bob", Age = 25, City = "Los Angeles" },
new Person { Name = "Charlie", Age = 35, City = "New York" },
new Person { Name = "Diana", Age = 28, City = "Chicago" },
new Person { Name = "Eve", Age = 30, City = "Los Angeles" }
};
// ===== QUERY SYNTAX (SQL-like) =====
Console.WriteLine("=== Query Syntax ===");
// Basic filtering and projection
var evenNumbers = from n in numbers
where n % 2 == 0
select n;
Console.WriteLine($"Even numbers: {string.Join(", ", evenNumbers)}");
// Grouping
var peopleByCity = from p in people
group p by p.City into cityGroup
select new { City = cityGroup.Key, Count = cityGroup.Count() };
foreach (var g in peopleByCity)
Console.WriteLine($"{g.City}: {g.Count}");
// ===== METHOD SYNTAX (Fluent) =====
Console.WriteLine("\n=== Method Syntax ===");
// Chaining operations
var oddSquares = numbers.Where(n => n % 2 != 0)
.Select(n => n * n)
.OrderByDescending(n => n);
Console.WriteLine($"Odd squares: {string.Join(", ", oddSquares)}");
// Aggregation
var sum = numbers.Sum();
var avg = numbers.Average();
var countOver5 = numbers.Count(n => n > 5);
Console.WriteLine($"Sum: {sum}, Avg: {avg:F2}, >5: {countOver5}");
// Complex filtering
var nyAdults = people.Where(p => p.City == "New York" && p.Age > 25)
.OrderBy(p => p.Age)
.Select(p => p.Name);
Console.WriteLine($"NY adults: {string.Join(", ", nyAdults)}");
// ===== SET OPERATIONS =====
int[] arr1 = { 1, 2, 3, 4, 5 };
int[] arr2 = { 4, 5, 6, 7, 8 };
Console.WriteLine("\n=== Set Operations ===");
Console.WriteLine($"Union: {string.Join(", ", arr1.Union(arr2))}");
Console.WriteLine($"Intersect: {string.Join(", ", arr1.Intersect(arr2))}");
Console.WriteLine($"Except: {string.Join(", ", arr1.Except(arr2))}");
// ===== QUANTIFIERS =====
Console.WriteLine("\n=== Quantifiers ===");
bool anyOver40 = people.Any(p => p.Age > 40);
bool allOver18 = people.All(p => p.Age > 18);
Console.WriteLine($"Any over 40: {anyOver40}, All over 18: {allOver18}");
// ===== ELEMENT OPERATORS =====
Console.WriteLine("\n=== Element Operators ===");
var firstNY = people.FirstOrDefault(p => p.City == "New York");
Console.WriteLine($"First NYer: {firstNY?.Name}");
// ===== ZIP =====
Console.WriteLine("\n=== Zip ===");
int[] ids = { 1, 2, 3, 4, 5 };
string[] names = { "One", "Two", "Three", "Four", "Five" };
var zipped = ids.Zip(names, (id, name) => $"{id}: {name}");
Console.WriteLine($"Zipped: {string.Join(", ", zipped)}");
// ===== AGGREGATE =====
Console.WriteLine("\n=== Aggregate ===");
var factorial = Enumerable.Range(1, 5).Aggregate((acc, x) => acc * x);
Console.WriteLine($"5! = {factorial}");
}
}
⚡ Async & Await
🎯 Complete Definition
Asynchronous programming with async/await (C# 5+) enables non-blocking operations, improving scalability and responsiveness. async methods return Task or Task<T> and can use await to suspend without blocking the thread.
⚡ Core Concepts
- async keyword: Marks method as asynchronous. Can return Task, Task<T>, ValueTask<T>, or void (event handlers only)
- await operator: Suspends method until awaited task completes, yielding control to caller
- Task/Task<T>: Represent asynchronous operations
- ValueTask<T>: Performance optimization for often-synchronous results
- CancellationToken: Cooperative cancellation
- IProgress<T>: Progress reporting
- Task.WhenAll/WhenAny: Wait for multiple tasks
- ConfigureAwait(false): Prevents capturing synchronization context
⚠️ Best Practices
- Avoid async void except event handlers
- Don't block on async code with .Result or .Wait() (causes deadlocks)
- Use ConfigureAwait(false) in library code
- Name async methods with "Async" suffix
- Handle exceptions properly (stored in Task)
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.Linq;
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Starting async operations...");
// ===== BASIC ASYNC/AWAIT =====
Console.WriteLine("\n=== Basic Async/Await ===");
int result = await ComputeSquareAsync(10);
Console.WriteLine($"Square of 10: {result}");
// ===== MULTIPLE TASKS CONCURRENTLY =====
Console.WriteLine("\n=== Concurrent Tasks ===");
var tasks = new[]
{
ComputeSquareAsync(5),
ComputeSquareAsync(6),
ComputeSquareAsync(7)
};
int[] results = await Task.WhenAll(tasks);
Console.WriteLine($"Squares: {string.Join(", ", results)}");
Console.WriteLine($"Sum: {results.Sum()}");
// ===== FIRST COMPLETED TASK =====
Console.WriteLine("\n=== First Completed Task ===");
var firstTask = await Task.WhenAny(
DelayedResultAsync(1, "First", 3000),
DelayedResultAsync(2, "Second", 2000),
DelayedResultAsync(3, "Third", 1000)
);
Console.WriteLine($"First completed: {await firstTask}");
// ===== HTTP REQUEST EXAMPLE =====
Console.WriteLine("\n=== HTTP Request ===");
await DownloadContentAsync("https://api.github.com");
// ===== PROGRESS REPORTING =====
Console.WriteLine("\n=== Progress Reporting ===");
var progress = new Progress<int>(p => Console.WriteLine($"Progress: {p}%"));
await ProcessWithProgressAsync(progress, CancellationToken.None);
// ===== CANCELLATION =====
Console.WriteLine("\n=== Cancellation ===");
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(2));
try
{
await LongRunningOperationAsync(cts.Token);
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was cancelled");
}
// ===== ASYNC STREAMS (IAsyncEnumerable) =====
Console.WriteLine("\n=== Async Streams ===");
await foreach (var num in GenerateNumbersAsync(5, 500))
{
Console.WriteLine($"Received: {num}");
}
// ===== ERROR HANDLING =====
Console.WriteLine("\n=== Error Handling ===");
try
{
await FailingOperationAsync();
}
catch (Exception ex)
{
Console.WriteLine($"Caught exception: {ex.Message}");
}
}
static async Task<int> ComputeSquareAsync(int input)
{
await Task.Delay(1000);
return input * input;
}
static async Task<string> DelayedResultAsync(int id, string name, int delayMs)
{
await Task.Delay(delayMs);
return $"{name} (ID: {id})";
}
static async Task DownloadContentAsync(string url)
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "C# App");
try
{
string content = await client.GetStringAsync(url);
Console.WriteLine($"Downloaded {content.Length} characters");
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Download error: {ex.Message}");
}
}
static async Task ProcessWithProgressAsync(IProgress<int> progress, CancellationToken cancellationToken)
{
for (int i = 0; i <= 100; i += 10)
{
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(200, cancellationToken);
progress?.Report(i);
}
}
static async Task LongRunningOperationAsync(CancellationToken cancellationToken)
{
for (int i = 0; i < 5; i++)
{
cancellationToken.ThrowIfCancellationRequested();
await Task.Delay(1000, cancellationToken);
Console.WriteLine($"Step {i + 1}/5 completed");
}
}
static async IAsyncEnumerable<int> GenerateNumbersAsync(int count, int delayMs)
{
for (int i = 1; i <= count; i++)
{
await Task.Delay(delayMs);
yield return i;
}
}
static async Task FailingOperationAsync()
{
await Task.Delay(100);
throw new InvalidOperationException("Something went wrong");
}
}
🚀 Advanced Features (C# 8-12)
🎯 Complete Definition
Modern C# (versions 8 through 12) introduces powerful features for productivity, safety, and expressiveness: nullable reference types, records, pattern matching enhancements, and more.
🚀 C# 8.0 Features (2019)
- Nullable reference types: Enable null-state analysis with #nullable enable
- Default interface methods: Interfaces can provide default implementations
- Async streams: IAsyncEnumerable<T> with await foreach
- Indices and ranges: ^ operator (end-relative), .. for ranges
- Using declarations: Simplified using without blocks
🚀 C# 9.0 Features (2020)
- Records: Immutable reference types with value equality: record Person(string Name, int Age);
- Init-only setters: Properties set only during init: { get; init; }
- Top-level statements: No explicit Main method for simple programs
- Pattern matching enhancements: Relational patterns, logical patterns (and, or, not)
- Target-typed new: Person p = new("Alice", 30); when type known
🚀 C# 10.0 Features (2021)
- Global using directives: global using System; applies to all files
- File-scoped namespaces: namespace MyNamespace; reduces indentation
- Record structs: Value-type records with record struct
- Extended property patterns: person is { Address.City: "New York" }
- Lambda improvements: Natural types, attributes on lambdas
🚀 C# 11.0 Features (2022)
- Required members: required modifier enforces property initialization
- Raw string literals: """ ... """ for multi-line strings with minimal escaping
- List patterns: Match arrays/lists: [1, 2, .. var rest]
- Static abstract members in interfaces: Enable generic math
- File-local types: file class limits visibility to single file
🚀 C# 12.0 Features (2023)
- Primary constructors: public class Person(string name, int age);
- Collection expressions: int[] array = [1, 2, 3]; spread .. operator
- Inline arrays: Fixed-size arrays for performance
- nameof in unbound generics: nameof(List<>)
- Default lambda parameters: (int x = 0) => x * x
using System;
using System.Collections.Generic;
// ===== C# 9: RECORDS =====
public record Person(string Name, int Age);
// ===== C# 10: RECORD STRUCTS =====
public record struct Point(int X, int Y)
{
public double Distance => Math.Sqrt(X * X + Y * Y);
}
// ===== C# 12: PRIMARY CONSTRUCTORS =====
public class Product(string name, decimal price)
{
public string Name { get; } = name;
public decimal Price { get; } = price;
public string GetInfo() => $"{Name}: {Price:C}";
}
// ===== C# 11: REQUIRED MEMBERS =====
public class Configuration
{
public required string ConnectionString { get; init; }
public required int TimeoutSeconds { get; init; }
}
// ===== C# 9: INIT-ONLY SETTERS =====
public class InitExample
{
public string Name { get; init; }
public int Age { get; init; }
}
// ===== C# 8: NULLABLE REFERENCE TYPES =====
#nullable enable
class NullableDemo
{
public string NonNullable { get; set; } = "";
public string? Nullable { get; set; }
}
// ===== C# 8: INDICES AND RANGES =====
class IndexRangeDemo
{
public void Demo()
{
int[] array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
// Index from end
Console.WriteLine($"Last: {array[^1]}"); // 9
Console.WriteLine($"Second last: {array[^2]}"); // 8
// Ranges
int[] firstThree = array[..3]; // [0,1,2]
int[] lastThree = array[^3..]; // [7,8,9]
int[] middle = array[3..7]; // [3,4,5,6]
Console.WriteLine($"First three: {string.Join(",", firstThree)}");
Console.WriteLine($"Last three: {string.Join(",", lastThree)}");
}
}
// ===== C# 11: LIST PATTERNS =====
class ListPatternDemo
{
public string MatchList(int[] numbers) => numbers switch
{
[] => "Empty",
[1] => "Single 1",
[1, 2] => "Exactly 1 and 2",
[1, 2, .. var rest] => $"Starts with 1,2 and has {rest.Length} more",
_ => "Other"
};
}
// ===== C# 12: COLLECTION EXPRESSIONS =====
class CollectionExpressionDemo
{
public void Demo()
{
// Collection literals
int[] array = [1, 2, 3, 4, 5];
List<string> list = ["a", "b", "c"];
// Spread operator
int[] more = [..array, 6, 7, 8];
Console.WriteLine($"Combined: {string.Join(",", more)}");
}
}
// ===== C# 11: RAW STRING LITERALS =====
class RawStringDemo
{
public string GetJson() => """
{
"name": "C#",
"version": 12
}
""";
}
// ===== C# 9: PATTERN MATCHING ENHANCEMENTS =====
class PatternMatchingDemo
{
public string Classify(object obj) => obj switch
{
> 0 and < 10 => "Small positive",
>= 10 and < 100 => "Medium",
>= 100 => "Large",
< 0 => "Negative",
string s when s.Length > 5 => "Long string",
_ => "Unknown"
};
}
// ===== TESTING ALL FEATURES =====
class Program
{
static void Main()
{
Console.WriteLine("C# 12 Advanced Features Demo");
// Records
var person = new Person("Alice", 30);
var person2 = person with { Age = 31 };
Console.WriteLine($"Record: {person}");
Console.WriteLine($"With expression: {person2}");
// Primary constructors
var product = new Product("Laptop", 999.99m);
Console.WriteLine(product.GetInfo());
// Required members
var config = new Configuration
{
ConnectionString = "Server=localhost;Database=test",
TimeoutSeconds = 30
};
// Collection expressions
int[] numbers = [1, 2, 3, 4, 5];
Console.WriteLine($"Collection expression: {string.Join(",", numbers)}");
// List patterns
var listDemo = new ListPatternDemo();
Console.WriteLine(listDemo.MatchList([1, 2, 3, 4]));
// Raw strings
var raw = new RawStringDemo();
Console.WriteLine(raw.GetJson());
// Indices and ranges
var indexDemo = new IndexRangeDemo();
indexDemo.Demo();
// Pattern matching
var patternDemo = new PatternMatchingDemo();
Console.WriteLine(patternDemo.Classify(42));
Console.WriteLine(patternDemo.Classify("Hello World"));
}
}