C#-OVERVEWS

Objectives: C#-OVERVEWS

Comprehensive C# Notes — Theory & Practical (Bootstrapped)

Comprehensive C# Notes

From history and environment setup to advanced features, LINQ, async, memory management, and exam-ready practicals. Code examples included and instructions to compile & run locally.

1. History & Purpose

C# (pronounced "C-sharp") was developed by Microsoft in the late 1990s and first released in 2002 as part of the .NET Framework. Designed by Anders Hejlsberg and the C# team, the language aimed to combine the power of C++ with ease of use of languages like Visual Basic, while enabling safe, managed code and modern features such as generics, LINQ, async/await and rich tooling.

  • Key milestones: C# 1.0 (2002), 2.0 (generics), 3.0 (LINQ), 4.0 (dynamic), 5.0 (async/await), later versions added tuples, pattern matching, records, nullable reference types, etc.
  • .NET family: .NET Framework > .NET Core > modern unified .NET (from .NET 5 onward). Use dotnet --version to check your SDK.

2. Setup — Tools & Running Code

Two main ways to run C# code:

  1. Locally with .NET SDK
    // Windows / macOS / Linux
    # install .NET SDK from https://dotnet.microsoft.com/
    dotnet new console -n MyApp
    cd MyApp
    dotnet run
            
  2. Online REPLs — use .NET Fiddle, sharplab.io, or try.dot.net for quick experiments.

Compiler & runtime notes:

  • dotnet build --- compile
  • dotnet run --- build & run
  • dotnet test --- run tests in test projects

3. Language Basics

3.1 Program structure

using System;

class Program {
  static void Main(string[] args) {
    Console.WriteLine("Hello, World!");
  }
}
    

3.2 Types

Value types vs Reference types.

  • Value: int, long, double, bool, struct
  • Reference: string, object, class, interface, delegate, array

3.3 Variables, constants, var

int x = 5;
const double PI = 3.14159;
var name = "Alice"; // compiler infers string
    

3.4 Control flow

// if/else
if (x > 0) Console.WriteLine("positive");

// switch (patterns)
switch (x) {
  case 0: ...; break;
  default: ...; break;
}

// loops: for, while, foreach
for (int i=0;i<10;i++) { }
foreach (var ch in "text") { }
    

3.5 Methods & parameters

int Add(int a, int b) {
  return a + b;
}

// default params, named args, ref, out
void Example(int x = 10, string msg = "hi") {}
void Swap(ref int a, ref int b) { int t=a; a=b; b=t; }

void Get(out int value) { value = 42; }
    

3.6 Strings & interpolation

string s = "hello";
string t = $"Value: {x}"; // interpolation
string path = @"C:\folder\file.txt"; // verbatim string
    

4. Object Oriented Programming (OOP)

4.1 Classes & objects

public class Person {
  public string Name { get; set; }
  public int Age { get; set; }

  public Person(string name, int age) {
    Name = name; Age = age;
  }

  public void Speak() => Console.WriteLine($"Hi I'm {Name}");
}
    

4.2 Inheritance & polymorphism

public class Employee : Person {
  public int Salary { get; set; }
  public override string ToString() => $"{Name} ({Age}) - {Salary}";
}

// polymorphism
Person p = new Employee("A",30) { Salary = 1000 };
Console.WriteLine(p.ToString());
    

4.3 Interfaces & abstract classes

public interface ILogger { void Log(string msg); }
public abstract class Shape { public abstract double Area(); }
    

4.4 Properties, indexers

public int X { get; private set; }
public string this[int index] { get { ... } set { ... } }
    

4.5 Structs vs classes

Structs are value types — use for small immutable data; classes are reference types.

5. Generics & Collections

List<int> numbers = new List<int>() {1,2,3};
Dictionary<string,int> map = new Dictionary<string,int>();

// generic method
T Echo<T>(T v) { return v; }
    

Important collections: List, Dictionary, HashSet, Queue, Stack, LinkedList. Use IEnumerable<T> and IList<T> when exposing APIs.

6. LINQ (Language Integrated Query)

LINQ brings SQL-like queries for collections.

var adults = people.Where(p => p.Age >= 18)
                     .OrderBy(p => p.Name)
                     .Select(p => p.Name);

// query syntax
var q = from p in people where p.Age >= 18 select p;
    

Common: Where, Select, OrderBy, GroupBy, Join, Any, All, First, FirstOrDefault, Sum, Count.

7. Exceptions & Error Handling

try {
  // code
} catch (ArgumentNullException ex) {
  Console.WriteLine(ex.Message);
} catch (Exception ex) {
  // generic
} finally {
  // cleanup
}
    

Best practices: catch specific exceptions, use using or try/finally for disposal (IDisposable).

8. Async / Await & Tasks

Use for non-blocking I/O and concurrency-friendly code.

async Task<int> GetAsync() {
  await Task.Delay(1000);
  return 42;
}

// call
int v = await GetAsync();
    

Key types: Task, Task<T>, ValueTask<T>. Avoid blocking on .Result or .Wait() — prefer await.

9. Memory Management & Performance

  • Managed memory with garbage collector (GC). Understand generations (0,1,2) and large object heap (LOH).
  • Use using or IAsyncDisposable for expected cleanup.
  • Prefer Span<T> and Memory<T> for high-performance scenarios.
  • Avoid unnecessary allocations; use pooling (ArrayPool<T>).

10. Advanced Topics

10.1 Delegates & Events

public delegate void Notify(string message);
public event Notify OnNotify;

// usage
OnNotify += msg => Console.WriteLine(msg);
OnNotify?.Invoke("Hi");
    

10.2 Reflection

// get type info
Type t = typeof(Person);
var props = t.GetProperties();
    

10.3 Attributes

[AttributeUsage(AttributeTargets.Class)]
public class MyAttr : Attribute { }

[MyAttr]
public class C { }
    

10.4 Pattern matching

if (obj is Person p && p.Age >= 18) { ... }
switch (shape) { case Circle c: ...; break; }
    

10.5 Records & immutability

public record Point(int X, int Y);
var p1 = new Point(1,2);
var p2 = p1 with { X = 5 };
    

10.6 Unsafe code & pointers

Use only when necessary for high-performance interop; requires unsafe and proper permissions.

11. .NET & Ecosystem — ASP.NET Core, EF Core

Brief points:

  • ASP.NET Core for building web APIs and web apps. Middleware, routing, dependency injection are core concepts.
  • Entity Framework Core for ORM; use migrations (dotnet ef migrations add).
  • Dependency injection is built in — register services in Program.cs with builder.Services.AddScoped<T>().

12. Testing & Debugging

  • Unit testing frameworks: xUnit, NUnit, MSTest. Use dotnet test.
  • Mocking: Moq, NSubstitute.
  • Use debugger, breakpoints, watch, immediate window; log with ILogger.

13. Practical Examples — Step-by-step

13.1 Console App: CRUD in-memory

using System;
using System.Collections.Generic;

var people = new List<Person>();

while (true) {
  Console.WriteLine("1-Add 2-List 3-Exit");
  var k = Console.ReadLine();
  if (k=="1") {
    Console.Write("Name: "); var n = Console.ReadLine();
    people.Add(new Person(n, 0));
  } else if (k=="2") {
    foreach (var p in people) Console.WriteLine(p.Name);
  } else break;
}

record Person(string Name, int Age);
    

13.2 Web API minimal example

// in Program.cs (ASP.NET Core minimal API)
var builder = WebApplication.CreateBuilder();
var app = builder.Build();

app.MapGet("/hello", () => "Hello from API");
app.Run();
    

13.3 EF Core snippet

public class AppDbContext : DbContext {
  public DbSet<Person> People { get; set; }
}

// register
builder.Services.AddDbContext<AppDbContext>(opt => opt.UseSqlite("Data Source=app.db"));
    

14. Exam-style Questions & Answers (Theory + Practical)

Q1: Explain difference between value and reference types.

A: Value types store data directly (stack), copying duplicates value; reference types store reference to heap object; assignment copies reference.

Q2: Write a method to reverse a string efficiently.

string Reverse(string s) {
  if (string.IsNullOrEmpty(s)) return s;
  var arr = s.ToCharArray();
  Array.Reverse(arr);
  return new string(arr);
}
    

Q3: Implement producer-consumer using BlockingCollection<T>.

using System.Collections.Concurrent;
var bc = new BlockingCollection<int>(boundedCapacity:100);
// producer
Task.Run(() => { for (int i=0;i<1000;i++) { bc.Add(i); } bc.CompleteAdding(); });
// consumer
Task.Run(() => { foreach (var item in bc.GetConsumingEnumerable()) Console.WriteLine(item); });
    

Q4 (practical): Create Web API endpoint to return top N users by score using EF Core.

app.MapGet("/top/{n}", async (int n, AppDbContext db) =>
  await db.Users.OrderByDescending(u => u.Score).Take(n).ToListAsync()
);
    

Q5: Explain async/await and deadlock causes.

A: async marks a method with awaitable operations. await yields control while awaiting a task. Deadlocks often happen when blocking on async code in sync context (e.g., .Result in UI apps) — avoid by using asynchronous call chains or ConfigureAwait(false) in libraries.

Q6: Memory leak scenarios in managed code?

Large object references held in static lists, event handlers not unsubscribed, or unmanaged resources not disposed. Use weak references or unsubscribe/Dispose.

15. Practical Exercises (with answers & difficulty levels)

  1. Easy — FizzBuzz program. (Answer: standard implementation using modulo.)
  2. Medium — Implement LRU cache using LinkedList<T> + Dictionary<K,V>. (Hint: store nodes in dictionary, move to front on access.)
  3. Hard — Build a small message bus supporting publishers/subscribers with topics and durable subscription simulation. (Use ConcurrentDictionary, BlockingCollection per topic.)

16. Quick Cheatsheet

  • ?. null-conditional operator
  • ?? null-coalescing
  • is pattern matching
  • using for IDisposable
  • record for immutable data
  • Span<T> for slices without allocations

17. Where to practice & read more

Recommended: Microsoft docs (docs.microsoft.com), C# language specification, .NET API docs, online judges (HackerRank, LeetCode), and interactive REPLs.

Reference Book: N/A

Author name: SIR H.A.Mwala Work email: biasharaboraofficials@gmail.com
#MWALA_LEARN Powered by MwalaJS #https://mwalajs.biasharabora.com
#https://educenter.biasharabora.com

:: 1.2::