A structured, beginner-to-proficient C# tutorial series with definitions, syntax, examples, and best practices.
Author: Arvind Kumar | GitHub:@arvind01A | Started: March 2026
10 days. Beginner → Expert. This repository is the complete C# Interview Roadmap — from fundamentals all the way to SOLID principles and Design Patterns. Thank you for following along! ⭐ Star this repo if it helped you.
This repository documents my complete C# revision — from basics to expert-level concepts. Each day includes:
| 📌 What's Inside | Description |
|---|---|
| 📝 Definitions | Clear, concise explanations |
| 💻 Syntax Examples | Ready-to-reference patterns |
| 📋 Code Snippets | Copy-paste ready code |
| Key differences & common mistakes | |
| 📊 Summary Tables | Quick-reference comparisons |
💡 Perfect for beginners, self-learners, or anyone refreshing C# skills in 2026!
Fundamentals → OOP → Collections → Exception Handling → File I/O → Expert_level-1 → Expert_level-2 → Expert_level-3
✅ ✅✅✅ ✅ ✅ ✅ ✅ ✅
| # | Day | Topic | Subtopics | Status |
|---|---|---|---|---|
| 1 | Day 1 | Fundamentals | Variables · Operators · Control Flow · Loops | ✅ Done |
| 2 | Day 2 | Classes & Objects | Methods · Parameters · Constructors · Fields | ✅ Done |
| 3 | Day 3 | OOP Pillars | Encapsulation · Inheritance · Abstraction · Polymorphism | ✅ Done |
| 4 | Day 4 | Data Structures | Arrays · Strings · StringBuilder · Tuples | ✅ Done |
| 5 | Day 5 | Generics | Generic Classes · Methods · Constraints | ✅ Done |
| 6 | Day 6 | Collections | Non-Generic · Generic · Specialized · Concurrent | ✅ Done |
| 7 | Day 7 | Exception & File Handling | try-catch-finally · throw vs throw ex · Built-in Exceptions · StreamReader/Writer · Async File I/O | ✅ Done |
| 8 | Day 8 | Expert I — Functional Programming & Delegates | Extension Methods · Lambda · LINQ · Pattern Matching · Action/Func/Predicate · Events | ✅ Done |
| 9 | Day 9 | Expert II — Multithreading, Async & Serialization | Thread · Task · Parallel.ForEach · Async/Await · IAsyncEnumerable · JSON/XML/Binary | ✅ Done |
| 10 | Day 10 | Expert III — Best Practices & Design Patterns | Naming · Clean Code · Null Safety · C# 12 Features · SOLID · Creational · Structural · Behavioral Patterns | ✅ Done |
🏁 Completed: March 14, 2026
Click to expand
intage=25;doubleprice=9.99;stringname="Arvind";boolisActive=true;chargrade='A';varinferred=42;// Type inferred by compilerconstdoublePI=3.14159;// Constant// Arithmeticintsum=10+5;// 15intmod=10%3;// 1// ComparisonboolisEqual=(5==5);// trueboolnotEqual=(5!=4);// true// Logicalboolresult=(true&&false);// falsebooleither=(true||false);// trueif(age>=18){Console.WriteLine("Adult");}elseif(age>=13){Console.WriteLine("Teen");}else{Console.WriteLine("Child");}stringlabel=ageswitch{>=18=>"Adult",>=13=>"Teen",
_ =>"Child"};for(inti=0;i<5;i++){}while(condition){}do{}while(condition);foreach(varitemincollection){}break;continue;return;// jump statementsClick to expand
publicintAdd(inta,intb)=>a+b;publicvoidSwap(refinta,refintb){(a,b)=(b,a);}publicvoidTryParse(strings,outintresult){result=int.Parse(s);}publicvoidGreet(stringname,stringgreeting="Hello")=>Console.WriteLine($"{greeting}, {name}!");Greet(name:"Arvind",greeting:"Hi");publicclassPerson{publicstringName{get;set;}publicintAge{get;set;}publicPerson(){}publicPerson(stringname)=>Name=name;publicPerson(Personother)=>(Name,Age)=(other.Name,other.Age);staticPerson(){/* runs once */}}publicclassCircle{privatedouble_radius;publicstaticintCount=0;publicreadonlydoubleId;}Click to expand
// EncapsulationpublicclassBankAccount{privatedecimal_balance;publicdecimalBalance{get=>_balance;privateset=>_balance=value>=0?value:0;}}// InheritancepublicclassAnimal{publicvirtualvoidSpeak()=>Console.WriteLine("...");}publicclassDog:Animal{publicoverridevoidSpeak()=>Console.WriteLine("Woof!");}// AbstractionpublicabstractclassShape{publicabstractdoubleArea();}publicinterfaceIDrawable{voidDraw();stringColor{get;set;}}// Polymorphism — runtimeAnimalanimal=newDog();animal.Speak();// "Woof!"Access Modifiers:
| Modifier | Accessible From |
|---|---|
public | Anywhere |
private | Same class only |
protected | Same class + subclasses |
internal | Same assembly |
protected internal | Same assembly or subclasses |
Click to expand
// Arraysint[]nums={1,2,3,4,5};int[,]matrix=newint[3,3];int[][]jagged=newint[3][];Array.Sort(nums);Array.Reverse(nums);// Stringsstringmsg=$"Name: {name}, Age: {age}";varsb=newStringBuilder();sb.Append("Hello");sb.AppendLine(" World");// Tuplesvarperson=(Name:"Arvind",Age:25,City:"Delhi");var(name,age,city)=person;Click to expand
publicclassBox<T>{publicTValue{get;set;}}publicclassPair<TKey,TValue>{publicTKeyKey;publicTValueValue;}publicstaticvoidSwap<T>(refTa,refTb)=>(a,b)=(b,a);| Constraint | Meaning |
|---|---|
where T : class | Reference types only |
where T : struct | Value types only |
where T : new() | Parameterless constructor |
where T : IComparable<T> | Must implement IComparable |
Click to expand
// Generic (preferred)List<int>numbers=new(){1,2,3};varscores=newDictionary<string,int>();varset=newHashSet<string>();varsorted=newSortedList<string,int>();// Concurrent (thread-safe)ConcurrentDictionary<string,int>dict=new();ConcurrentQueue<string>queue=new();| Collection | Ordered | Unique | Key-Value | Thread-Safe |
|---|---|---|---|---|
List<T> | ✅ | ❌ | ❌ | ❌ |
Dictionary<K,V> | ❌ | ✅ Keys | ✅ | ❌ |
HashSet<T> | ❌ | ✅ | ❌ | ❌ |
ConcurrentDictionary | ❌ | ✅ Keys | ✅ | ✅ |
Click to expand
// try-catch-finallytry{intr=10/int.Parse("0");}catch(DivideByZeroExceptionex){Console.WriteLine(ex.Message);}finally{Console.WriteLine("Cleanup!");}// throw vs throw excatch(Exceptionex){Log(ex);throw;}// ✅ preserves stack tracecatch(Exceptionex){Log(ex);throwex;}// ❌ resets stack trace// File I/Ousingvarwriter=newStreamWriter("notes.txt");writer.WriteLine("Hello!");stringcontent=File.ReadAllText("notes.txt");awaitFile.WriteAllTextAsync("out.txt","async write");stringpath=Path.Combine("logs","app.log");Click to expand
// Extension MethodspublicstaticstringCapitalize(thisstrings)=>string.IsNullOrEmpty(s)?s:char.ToUpper(s[0])+s[1..];"hello".Capitalize();// "Hello"// Lambda & LINQFunc<int,int>square= x =>x*x;varresult=students.Where(s =>s.Score>=80).OrderByDescending(s =>s.Score).Select(s =>s.Name);// Pattern Matchingstringdesc=shapeswitch{Circlecwhenc.Radius>10=>"Large circle",Rectangler=>$"{r.Width}x{r.Height}",
_ =>"Unknown"};// Delegates & EventsAction<string>greet= name =>Console.WriteLine($"Hi {name}!");Func<int,int>sq= x =>x*x;Predicate<int>even= n =>n%2==0;publiceventEventHandler<OrderEventArgs> OrderPlaced;
OrderPlaced?.Invoke(this,newOrderEventArgs(item));Click to expand
// ThreadThreadt=newThread(()=>{Thread.Sleep(500);Console.WriteLine("Done");});t.IsBackground=true;t.Start();t.Join();// Task (preferred)Task<int>task=Task.Run(()=>42);intresult=awaittask;int[]all=awaitTask.WhenAll(t1,t2,t3);// Parallel (CPU-bound)Parallel.ForEach(items, item =>ProcessItem(item));Parallel.Invoke(()=>TaskA(),()=>TaskB());// Async/AwaitpublicasyncTask<string>FetchAsync(stringurl){usingvarclient=newHttpClient();returnawaitclient.GetStringAsync(url);}// Async Streamsawaitforeach(intnuminGenerateNumbersAsync(10))Console.WriteLine(num);// Serializationstringjson=JsonSerializer.Serialize(person,newJsonSerializerOptions{WriteIndented=true});Person?p=JsonSerializer.Deserialize<Person>(json);| Format | Readable | Speed | Use Case |
|---|---|---|---|
| JSON | ✅ | Fast | APIs, web |
| XML | ✅ | Slow | Legacy, SOAP |
| Binary | ❌ | ⚡ Fastest | Cache, IPC |
Click to expand
// Classes, Methods, Properties → PascalCasepublicclassOrderService{}publicvoidPlaceOrder(){}publicstringCustomerName{get;set;}// Local variables, parameters → camelCaseintorderCount=0;voidProcess(stringorderItem){}// Private fields → _camelCaseprivatereadonlystring_connectionString;// Constants → PascalCasepublicconstintMaxRetries=3;// Interfaces → I prefixpublicinterfaceIOrderRepository{}// Generics → T prefixpublicclassRepository<TEntity>{}// ✅ Small, focused methodspublicasyncTaskProcessOrderAsync(Orderorder){await_validator.ValidateAsync(order);await_pricer.CalculateTotalAsync(order);await_repository.SaveAsync(order);await_notifier.SendConfirmationAsync(order);}// ✅ No magic numbers — use enumspublicenumUserRole{Guest=0,User=1,Admin=2}if(user.Role==UserRole.Admin){}// ✅ Expression bodies for simple memberspublicstringFullName=> $"{FirstName} {LastName}";// ✅ Dispose resourcesusingvarconn=newSqlConnection(connStr);awaitusingvarstream=File.OpenWrite("out.txt");stringname="Arvind";// non-nullablestring?email=null;// nullableint?length=email?.Length;// null-conditionalstringdisplay=name??"Anonymous";// null-coalescingcache??=newDictionary<string,int>();// null-coalescing assignmentArgumentNullException.ThrowIfNull(name);// C# 10+ guard// Required properties (C# 11+)publicclassOrder{publicrequiredstringId{get;init;}publicrequiredstringCustomerName{get;init;}}// Records (C# 9+)publicrecordPerson(stringName,intAge);varp2=p1with{Age=26};// non-destructive mutation// Global usings (C# 10+)globalusingSystem.Text.Json;// File-scoped namespace (C# 10+)namespaceMyApp.Services;// Primary constructors (C# 12+)publicclassOrderService(IOrderRepositoryrepo,ILogger<OrderService>logger){}// Collection expressions (C# 12+)int[]nums=[1,2,3,4,5];int[]merged=[..nums,6,7];// Raw string literals (C# 11+)stringjson=""" { "name": "Arvind", "age": 25 } """;// ❌ One class doing everything// ✅ Separate concernspublicclassUserRepository{publicvoidSave(Useru){}}publicclassEmailService{publicvoidSendWelcome(Useru){}}publicclassUserReportService{publicstringGenerate(Useru)=>"";}// ✅ Extend by adding new classes, never modify existingpublicabstractclassShape{publicabstractdoubleArea();}publicclassCircle:Shape{publicoverridedoubleArea()=>Math.PI*Radius*Radius;}publicclassRectangle:Shape{publicoverridedoubleArea()=>Width*Height;}publicclassTriangle:Shape{publicoverridedoubleArea()=>0.5*Base*Height;}// ✅ Subclasses must honour base class contractspublicabstractclassShape{publicabstractdoubleArea();}publicclassRectangle:Shape{publicintWidth,Height;publicoverridedoubleArea()=>Width*Height;}publicclassSquare:Shape{publicintSide;publicoverridedoubleArea()=>Side*Side;}// ✅ Small focused interfacespublicinterfaceIWorkable{voidWork();}publicinterfaceIEatable{voidEat();}publicclassHumanWorker:IWorkable,IEatable{publicvoidWork(){}publicvoidEat(){}}publicclassRobotWorker:IWorkable{publicvoidWork(){}}// ✅ Depend on abstractions, inject implementationspublicinterfaceIOrderRepository{TaskSaveAsync(Ordero);}publicclassOrderService{privatereadonlyIOrderRepository_repo;publicOrderService(IOrderRepositoryrepo)=>_repo=repo;publicasyncTaskPlaceOrderAsync(Ordero)=>await_repo.SaveAsync(o);}// ASP.NET Core DIbuilder.Services.AddScoped<IOrderRepository,SqlOrderRepository>();publicsealedclassAppConfig{privatestaticreadonlyLazy<AppConfig>_instance=new(()=>newAppConfig());privateAppConfig(){}publicstaticAppConfigInstance=>_instance.Value;publicstringConnectionString{get;set;}="";}AppConfig.Instance.ConnectionString="Server=...";publicstaticNotificationCreate(stringtype)=>typeswitch{"email"=>newEmailNotification(),"sms"=>newSmsNotification(),"push"=>newPushNotification(),
_ =>thrownewArgumentException($"Unknown: {type}")};Notification.Create("email").Send("Order confirmed!");stringquery=newQueryBuilder().From("Orders").Where("Status = 'Active'").Where("CustomerId = 42").OrderBy("CreatedAt DESC").Limit(10).Build();publicinterfaceIRepository<T>whereT:class{Task<T?>GetByIdAsync(intid);Task<IEnumerable<T>>GetAllAsync();TaskAddAsync(Tentity);TaskDeleteAsync(intid);}// Base → CachedOrderService → LoggedOrderService// Each wraps the inner and adds cross-cutting concernspublicclassCachedOrderService:IOrderService{privatereadonlyIOrderService_inner;privatereadonlyIMemoryCache_cache;publicasyncTask<Order>GetOrderAsync(intid){if(_cache.TryGetValue(id,outOrder?cached))returncached!;varorder=await_inner.GetOrderAsync(id);_cache.Set(id,order,TimeSpan.FromMinutes(5));returnorder;}}publicclassStockTicker{publiceventEventHandler<StockEventArgs>?PriceChanged;privatedecimal_price;publicdecimalPrice{get=>_price;set{_price=value;PriceChanged?.Invoke(this,new("AAPL",value));}}}ticker.PriceChanged+=(s,e)=>Console.WriteLine($"[Alert] {e.Symbol}: ${e.Price}");publicinterfaceISortStrategy<T>{IEnumerable<T>Sort(IEnumerable<T>data);}publicclassAscendingSort<T>:ISortStrategy<T>whereT:IComparable<T>{publicIEnumerable<T>Sort(IEnumerable<T>d)=>d.OrderBy(x =>x);}publicclassDescendingSort<T>:ISortStrategy<T>whereT:IComparable<T>{publicIEnumerable<T>Sort(IEnumerable<T>d)=>d.OrderByDescending(x =>x);}varprocessor=newDataProcessor<int>(newAscendingSort<int>());processor.SetStrategy(newDescendingSort<int>());// swap at runtimevarpipeline=newValidationHandler();pipeline.SetNext(newPricingHandler()).SetNext(newPersistenceHandler());awaitpipeline.HandleAsync(order);// ✅ Validated → ✅ Priced → ✅ Saved to DBDesign Patterns Quick Reference:
| Category | Pattern | Problem Solved |
|---|---|---|
| Creational | Singleton | One instance needed globally |
| Creational | Factory Method | Decouple object creation |
| Creational | Builder | Complex multi-step construction |
| Structural | Repository | Abstract data access |
| Structural | Decorator | Add behaviour without inheritance |
| Behavioral | Observer | Notify multiple subscribers |
| Behavioral | Strategy | Swap algorithms at runtime |
| Behavioral | Chain of Responsibility | Pipeline / middleware processing |
csharp-learning/
│
├── 📁 day1/ ← Fundamentals
│ ├── 01-Variables/
│ ├── 02-Operators/
│ ├── 03-control-statements/
│ ├── 04-jump-statements/
│ └── 05-loops/
│
├── 📁 day2/ ← Classes & Objects
│ ├── 01-Methods-and-Parameters/
│ │ ├── 01-Return-Types/
│ │ ├── 02-Parameter-Passing/
│ │ ├── 03-Optional-Parameters/
│ │ └── 04-Named-Arguments/
│ ├── 02-Constructors/
│ │ ├── 01-Default/
│ │ ├── 02-Parameterized/
│ │ ├── 03-Overloading/
│ │ └── 04-Static-and-Copy/
│ └── 03-Fields/
│
├── 📁 day3/ ← OOP 4 Pillars
│ ├── 01-Encapsulation/
│ │ ├── 01-Access-Modifiers/
│ │ └── 02-Properties/
│ ├── 02-Inheritance/
│ │ ├── 01-Types-of-Inheritance/
│ │ └── 02-base-and-this-keywords/
│ ├── 03-Abstraction/
│ │ └── Abstract-Classes-and-Interfaces/
│ ├── 04-Polymorphism/
│ │ ├── 01-Compile-Time/
│ │ └── 02-Runtime/
│ └── 05-Indexers/
│
├── 📁 day4/ ← Basic Data Structures
│ ├── Arrays/
│ │ ├── Single-Dimensional/
│ │ ├── Array-Methods/
│ │ ├── Array-Class/
│ │ └── Multi-Dim-and-Jagged/
│ ├── Strings/
│ │ ├── String-Operations/
│ │ ├── Interpolation/
│ │ └── String-vs-StringBuilder/
│ └── Tuples/
│ └── Named-Tuples/
│
├── 📁 day5/ ← Generics
│ ├── Generic-Classes/
│ │ ├── Box<T>
│ │ ├── Pair<TKey
│ │ └── TValue>
│ ├── Generic-Methods/
│ │ ├── Explicit
│ │ └── Type Inference
│ └── Constraints/
│ ├── class
│ ├── struct
│ ├── new()
│ └── IComparable
│
├── 📁 day6/ ← Collections/ Advance Data Structures
│ ├── Non-Generic/ │ │ ├── ArrayList
│ │ ├── Hashtable
│ │ ├── Queue
│ │ └── Stack
│ ├── Generic/ │ │ ├── List<T>
│ │ ├── Dictionary
│ │ ├── HashSet
│ │ └── LinkedList
│ └── Specialized/ │ └── Concurrent Collections
│
├── 📁 day7/ ← Exception & File Handling
│ ├── Exception-Handling/
│ └── File-Handling/
│
├── 📁 day8/ ← Expert I: Functional Programming & Delegates
│ ├── Functional-Programming/
│ ├── Delegates/
│ └── Events/
│
├── 📁 day9/ ← Expert II: Multithreading, Async & Serialization
│ ├── Multithreading/
│ │ ├── 01-Thread-Class/
│ │ ├── 02-Task-Class/
│ │ └── 03-Parallel-ForEach/
│ ├── Async-Programming/
│ │ ├── 01-Async-and-Await/
│ │ ├── 02-Exception-Handling-in-Async/
│ │ └── 03-Async-Streams-IAsyncEnumerable/
│ └── Serialization/
│ ├── 01-JSON-Serialization/
│ ├── 02-XML-Serialization/
│ └── 03-Binary-Serialization/
│
├── 📁 day10/ ← Expert III: Best Practices & Design Patterns
│ ├── Best-Practices/
│ │ ├── 01-Naming-Conventions/
│ │ ├── 02-Clean-Code/
│ │ ├── 03-Null-Safety/
│ │ └── 04-Modern-CSharp-Features/
│ └── SOLID-and-Design-Patterns/
│ ├── 01-SOLID-Principles/
│ │ ├── S-Single-Responsibility/
│ │ ├── O-Open-Closed/
│ │ ├── L-Liskov-Substitution/
│ │ ├── I-Interface-Segregation/
│ │ └── D-Dependency-Inversion/
│ ├── 02-Creational-Patterns/
│ │ ├── Singleton/
│ │ ├── Factory-Method/
│ │ └── Builder/
│ ├── 03-Structural-Patterns/
│ │ ├── Repository/
│ │ └── Decorator/
│ └── 04-Behavioral-Patterns/
│ ├── Observer/
│ ├── Strategy/
│ └── Chain-of-Responsibility/
│
└── 📄 README.md
| Tool | Version | Purpose |
|---|---|---|
| Visual Studio | 2026 | Primary IDE |
| .NET SDK | 10.0 | Runtime & tooling |
| C# | 14 | Language version |
| Git | Latest | Version control |
# 1. Clone the repository
git clone https://github.com/arvind01A/csharp-learning.git
cd csharp-learning
# 2. Navigate to any daycd day1/01-Variables
# 3. Run any .cs file
dotnet script Program.cs
# or
dotnet runFound a mistake? Have a better explanation?
- ⭐ Star this repo if it helped you
- 🐛 Open an issue for corrections or suggestions
- 🍴 Fork & PR if you'd like to contribute notes
Made with ❤️ and ☕ by Arvind Kumar
"The best way to learn is to teach." — Keep pushing forward! 🚀