This complete C# tutorial covers 121 topics — from language fundamentals and OOP to LINQ, async, EF Core, ASP.NET Core Web APIs, and a final full-stack style .NET application project.
Course roadmap
- Introduction to C#
- What is C#?
- Features of C#
- C# vs C++ vs Java
- .NET and C# Relationship
- Installing .NET SDK
- Setting Up Visual Studio / VS Code for C#
- First C# Program
- C# Project Structure
- Compilation and Execution in C#
- C# Syntax
- Comments in C#
- Variables and Constants in C#
- Data Types in C#
- Value Types vs Reference Types in C#
- Type Casting in C#
- Nullable Types in C#
- Input and Output in C#
- Operators in C#
- Arithmetic Operators in C#
- Comparison Operators in C#
- Logical Operators in C#
- Assignment Operators in C#
- Bitwise Operators in C#
- Null-Coalescing Operators in C#
- Conditional Operator in C#
- Conditional Statements in C#
- if, else if and else in C#
- switch Statement in C#
- Pattern Matching in C#
- Loops in C#
- for Loop in C#
- while Loop in C#
- do-while Loop in C#
- foreach Loop in C#
- break and continue in C#
- Methods in C#
- Method Parameters in C#
- Return Values in C#
- Method Overloading in C#
- Optional Parameters in C#
- Named Arguments in C#
- Params Keyword in C#
- Recursion in C#
- Arrays in C#
- Multidimensional Arrays in C#
- Strings in C#
- String Methods in C#
- String Interpolation in C#
- StringBuilder in C#
- Classes and Objects in C#
- Constructors in C#
- Destructors in C#
- Properties in C#
- Fields in C#
- Access Modifiers in C#
- Encapsulation in C#
- Inheritance in C#
- Types of Inheritance in C#
- Polymorphism in C#
- Method Overriding in C#
- Virtual and Override in C#
- Abstract Classes in C#
- Interfaces in C#
- Sealed Classes in C#
- Static Classes and Members in C#
- Structs in C#
- Enums in C#
- Records in C#
- Generics in C#
- Generic Classes in C#
- Generic Methods in C#
- Collections in C#
- List<T> in C#
- Dictionary in C#
- HashSet in C#
- Queue in C#
- Stack in C#
- LINQ in C#
- LINQ Query Syntax in C#
- Lambda Expressions in C#
- Delegates in C#
- Events in C#
- Anonymous Methods in C#
- Extension Methods in C#
- Nullable Reference Types in C#
- Exception Handling in C#
- try, catch, finally in C#
- throw and Custom Exceptions in C#
- File Handling in C#
- Reading and Writing Files in C#
- JSON Handling in C#
- Serialization and Deserialization in C#
- Date and Time in C#
- Regular Expressions in C#
- Async and Await in C#
- Task and Task-Based Programming in C#
- Multithreading in C#
- Dependency Injection in C#
- Reflection in C#
- Attributes in C#
- Memory Management and Garbage Collection in C#
- C# with SQL Server
- Entity Framework Core
- CRUD with Entity Framework Core
- ASP.NET Core Introduction
- MVC Architecture in ASP.NET Core
- ASP.NET Core Web API
- REST API Development with C#
- Authentication and Authorization in ASP.NET Core
- JWT Authentication in ASP.NET Core
- Entity Framework Core with Web API
- API Documentation with Swagger in ASP.NET Core
- Unit Testing with xUnit
- Debugging C# Applications
- Logging in .NET
- Git and GitHub for C# Projects
- C# Security Best Practices
- C# Interview Questions
- Real-World C# Project
- Final Project – Complete ASP.NET Core Application
1. Introduction to C#
C# is a modern, strongly typed language on .NET used for web APIs, desktop apps, games, and cloud services. This series covers syntax, OOP, collections, LINQ, async, EF Core, ASP.NET Core, and a complete final project.
- Install .NET SDK and run Hello World.
- Learn OOP, LINQ, and async.
- Build the final ASP.NET Core application.
Learning path
Setup + first program
Types + OOP + collections
LINQ + async + files
EF Core + ASP.NET Core Web API
Auth, testing, security
Final ASP.NET Core app
2. What is C#?
C# combines strong typing, productive tooling, and a large BCL (Base Class Library) for building reliable applications.
C# at a glance
Strongly typed
OOP + modern features
Runs on .NET
Web, desktop, cloud, games
3. Features of C#
Modern C# includes records, pattern matching, nullable reference types, and top-level statements.
Feature highlights
Garbage collection
Properties / events
LINQ
async/await
Generics
Pattern matching
Nullable reference types
4. C# vs C++ vs Java
C# and Java are managed runtimes; C++ is typically unmanaged with manual/RAII memory control.
Quick compare
C++ → performance control, manual/RAII memory
Java → JVM ecosystem
C# → .NET ecosystem, modern language features
All → OOP capable
5. .NET and C# Relationship
.NET provides the runtime, BCL, and app models; C# is the primary language for many .NET apps.
.NET stack
C# source
→ Roslyn compiler
→ IL
→ .NET runtime (JIT/AOT)
→ BCL + packages
6. Installing .NET SDK
The SDK includes the runtime and CLI for creating/building/running projects.
- Download/install .NET SDK.
- Verify with dotnet –version.
- Create a sample console app.
Verify SDK
dotnet --version
dotnet --info
7. Setting Up Visual Studio / VS Code for C#
Use the IDE for IntelliSense, debugging, and test runners.
Setup tip
Visual Studio → workloads for .NET
VS Code → C# extension / Dev Kit
dotnet new / build / run in terminal
8. First C# Program
Confirm tooling works before learning language details.
- Run dotnet new console.
- Open Program.cs.
- dotnet run.
Hello World
Console.WriteLine("Hello, C#!");
9. C# Project Structure
SDK-style projects keep configuration concise in the .csproj file.
Project pieces
.csproj
Program.cs
Namespaces / folders
appsettings.json (web)
Properties/
10. Compilation and Execution in C#
`dotnet build` compiles; `dotnet run` builds and executes.
CLI
dotnet build
dotnet run
dotnet publish -c Release
11. C# Syntax
Prefer clear names and consistent formatting (dotnet format / IDE).
Syntax sample
var count = 10;
if (count > 0)
{
Console.WriteLine("positive");
}
12. Comments in C#
Use /// for public API documentation.
Comments
// Single line
/* Multi-line */
/// <summary>Adds two numbers.</summary>
13. Variables and Constants in C#
Prefer meaningful names; use readonly for instance immutability after construction.
Variables
int count = 0;
const double Pi = 3.14159;
readonly string id;
14. Data Types in C#
Know aliases (int → System.Int32) and when to use decimal for money.
Common types
int, long, double, decimal, bool, char
string, object
DateTime, Guid
Custom classes/structs/records
15. Value Types vs Reference Types in C#
Structs/enums are value types; classes/interfaces/delegates are reference types (with nuances).
Mental model
Value → copy data
Reference → copy reference
string is reference but immutable
Careful with mutable structs
16. Type Casting in C#
Prefer pattern matching `is` checks over risky casts.
Casting
double d = 3.7;
int n = (int)d; // 3
if (obj is string s) Console.WriteLine(s);
17. Nullable Types in C#
Use HasValue/Value or null-coalescing carefully.
Nullable
int? age = null;
int years = age ?? 0;
18. Input and Output in C#
For apps, prefer structured logging over Console in production services.
Console I/O
Console.Write("Name: ");
var name = Console.ReadLine();
Console.WriteLine($"Hello, {name}");
19. Operators in C#
Null-conditional ?. and null-coalescing ?? are everyday tools.
Operator groups
Arithmetic
Comparison
Logical
Assignment
Bitwise
?? / ??= / ?.
20. Arithmetic Operators in C#
Prefer decimal for currency math.
Arithmetic
var q = 10 / 3; // 3
var r = 10 % 3; // 1
var f = 10.0 / 3; // ~3.33
21. Comparison Operators in C#
For strings, be aware of culture/ordinal comparison choices.
Comparison
if (score >= 50) { /* pass */ }
string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
22. Logical Operators in C#
Useful for guard clauses.
Logical
if (user is not null && user.IsActive)
{
/* ... */
}
23. Assignment Operators in C#
??= assigns only when null.
Assignment
var n = 5;
n += 2;
name ??= "Guest";
24. Bitwise Operators in C#
Common for flags enums.
Bitwise / flags tip
[Flags] enum Perms { None = 0, Read = 1, Write = 2 }
var p = Perms.Read | Perms.Write;
25. Null-Coalescing Operators in C#
Helps write concise null-tolerant code.
Null operators
var city = user?.Address?.City ?? "Unknown";
cache ??= new Dictionary<string, int>();
26. Conditional Operator in C#
Prefer clarity over clever nesting.
Ternary
var label = score >= 50 ? "Pass" : "Retry";
27. Conditional Statements in C#
Use early returns to keep methods flat.
Branching tools
if / else if / else
switch / switch expressions
pattern matching
28. if, else if and else in C#
Brace consistently for maintainability.
if/else
if (temp >= 30) Console.WriteLine("Hot");
else if (temp >= 20) Console.WriteLine("Warm");
else Console.WriteLine("Cool");
29. switch Statement in C#
Switch expressions are concise for mapping values.
Switch expression
var label = status switch
{
"paid" => "Completed",
"pending" => "Waiting",
_ => "Other"
};
30. Pattern Matching in C#
Patterns reduce casting and nested conditionals.
Pattern
if (shape is Circle { Radius: > 0 } c)
{
Console.WriteLine(c.Radius);
}
31. Loops in C#
foreach is preferred for collections when you don’t need indexes.
Loop choices
for → indexes
foreach → sequences
while / do-while → conditions
LINQ → declarative transforms
32. for Loop in C#
Be careful with bounds and off-by-one errors.
for
for (var i = 0; i < items.Length; i++)
{
Console.WriteLine(items[i]);
}
33. while Loop in C#
Ensure termination conditions are reachable.
while
var n = 3;
while (n > 0)
{
Console.WriteLine(n);
n--;
}
34. do-while Loop in C#
Useful for menus and retry prompts.
do-while
int choice;
do {
Console.WriteLine("1) Run 0) Quit");
int.TryParse(Console.ReadLine(), out choice);
} while (choice != 0);
35. foreach Loop in C#
Don’t modify a collection while enumerating it (unless using safe patterns).
foreach
foreach (var item in items)
{
Console.WriteLine(item);
}
36. break and continue in C#
Use sparingly for readability.
break/continue
foreach (var n in nums)
{
if (n < 0) continue;
if (n == 0) break;
Console.WriteLine(n);
}
37. Methods in C#
Instance methods vs static methods; keep methods focused.
Method
static int Add(int a, int b) => a + b;
38. Method Parameters in C#
Prefer returning values over many out params.
Parameters
void Swap(ref int a, ref int b) => (a, b) = (b, a);
bool TryParseAge(string s, out int age) => int.TryParse(s, out age);
39. Return Values in C#
Expression-bodied members keep simple returns concise.
Return / tuple
(int min, int max) Range(int[] a) => (a.Min(), a.Max());
40. Method Overloading in C#
Return type alone cannot overload.
Overload
int Add(int a, int b) => a + b;
double Add(double a, double b) => a + b;
41. Optional Parameters in C#
Defaults must be compile-time constants (with some exceptions).
Optional
void Greet(string name = "Guest") => Console.WriteLine($"Hi {name}");
42. Named Arguments in C#
Especially helpful with multiple optional booleans.
Named args
CreateUser(name: "Asha", isAdmin: false);
43. Params Keyword in C#
params must be the last parameter.
params
int Sum(params int[] values) => values.Sum();
var total = Sum(1, 2, 3, 4);
44. Recursion in C#
Watch stack depth; prefer iterative/LINQ when simpler.
Recursion
long Factorial(int n) => n <= 1 ? 1 : n * Factorial(n - 1);
45. Arrays in C#
Prefer List<T> when size changes frequently.
Array
int[] scores = { 90, 85, 88 };
Console.WriteLine(scores.Length);
46. Multidimensional Arrays in C#
Jagged arrays are arrays of arrays — flexible but different memory layout.
2D array
int[,] grid = { { 1, 2 }, { 3, 4 } };
47. Strings in C#
Concatenation in loops should use StringBuilder.
String
string name = "Asha";
string hi = "Hello, " + name;
48. String Methods in C#
Prefer ordinal/invariant comparisons when appropriate.
String methods
var parts = "a,b,c".Split(',');
var ok = email.Contains('@', StringComparison.Ordinal);
49. String Interpolation in C#
Use raw string literals (modern C#) for multi-line text when helpful.
Interpolation
var msg = $"Order #{id} total={total:C}";
50. StringBuilder in C#
Ideal inside loops and serializers.
StringBuilder
var sb = new StringBuilder();
foreach (var w in words) sb.Append(w).Append(' ');
var text = sb.ToString();
51. Classes and Objects in C#
Prefer small classes with clear responsibilities.
Class
class User
{
public string Name { get; set; } = "";
public void Greet() => Console.WriteLine($"Hi {Name}");
}
52. Constructors in C#
Validate inputs; prefer required properties / init where suitable.
Constructor
class User
{
public User(string name) => Name = name;
public string Name { get; }
}
53. Destructors in C#
Don’t rely on destructors for timely resource cleanup — implement Dispose.
Cleanup tip
Prefer IDisposable / using
Finalizers are non-deterministic
SafeHandle for unmanaged resources
54. Properties in C#
Auto-properties keep code concise; add logic when validating.
Properties
public string Email { get; set; } = "";
public string Id { get; init; } = Guid.NewGuid().ToString("N");
55. Fields in C#
Prefer private fields with underscore naming if your style guide uses it.
Field
private readonly List<string> _items = new();
56. Access Modifiers in C#
Default for class members is private.
Modifiers
public
private
protected
internal
protected internal
private protected
57. Encapsulation in C#
Validate in setters/methods to protect invariants.
Encapsulation tip
Private fields
Public properties/methods
Validate inputs
Minimize mutable surface
58. Inheritance in C#
C# supports single class inheritance + multiple interfaces.
Inheritance
class Animal { public virtual void Speak() {} }
class Dog : Animal { public override void Speak() => Console.WriteLine("Woof"); }
59. Types of Inheritance in C#
Prefer composition when deep hierarchies get brittle.
Inheritance style
Single class inheritance
Interface implementation (many)
Composition over deep trees
60. Polymorphism in C#
Interfaces enable polymorphism without a shared class base.
Polymorphism
Animal a = new Dog();
a.Speak();
61. Method Overriding in C#
Use sealed override to stop further overriding.
override
public override void Speak() => Console.WriteLine("Woof");
62. Virtual and Override in C#
new hides members (different from override) — avoid accidental hiding.
virtual tip
virtual → can override
override → replace virtual/abstract
abstract → must override
new → hide (careful)
63. Abstract Classes in C#
Cannot instantiate abstract classes; derived types must implement abstracts.
Abstract
abstract class Shape
{
public abstract double Area();
}
64. Interfaces in C#
Default interface methods exist but use carefully for API evolution.
Interface
interface ILogger { void Log(string message); }
class ConsoleLogger : ILogger
{
public void Log(string message) => Console.WriteLine(message);
}
65. Sealed Classes in C#
Sealing can clarify design and enable some optimizations.
Sealed
sealed class PaymentService { /* ... */ }
66. Static Classes and Members in C#
Static classes cannot be instantiated; watch thread-safety for static mutable state.
Static
static class MathUtil
{
public static int Square(int n) => n * n;
}
67. Structs in C#
Prefer readonly struct for immutable values; avoid large mutable structs.
Struct
readonly struct Point(int X, int Y);
68. Enums in C#
Use [Flags] for bit fields; don’t assume contiguous values in loops blindly.
Enum
enum Status { Pending, Paid, Cancelled }
69. Records in C#
Records give value-based equality and with-expressions.
Record
record User(string Id, string Email);
var u2 = u1 with { Email = "new@example.com" };
70. Generics in C#
Constraints (where T : …) communicate requirements.
Generic idea
T Max<T>(T a, T b) where T : IComparable<T>
=> a.CompareTo(b) >= 0 ? a : b;
71. Generic Classes in C#
Generics power List<T>, Dictionary<TKey,TValue>, and your domain containers.
Generic class
class Box<T>
{
public Box(T value) => Value = value;
public T Value { get; }
}
72. Generic Methods in C#
Type inference usually supplies T at the call site.
Generic method
void PrintAll<T>(IEnumerable<T> items)
{
foreach (var i in items) Console.WriteLine(i);
}
73. Collections in C#
Choose List, Dictionary, HashSet, Queue, Stack by access pattern.
Collection map
List → sequence
Dictionary → key/value
HashSet → unique set
Queue/Stack → FIFO/LIFO
74. List<T> in C#
The most common collection for app code.
List
var items = new List<string> { "a", "b" };
items.Add("c");
75. Dictionary in C#
Use TryGetValue to avoid KeyNotFoundException.
Dictionary
var ages = new Dictionary<string, int> { ["Asha"] = 30 };
if (ages.TryGetValue("Asha", out var age)) Console.WriteLine(age);
76. HashSet in C#
Great for dedupe and membership tests.
HashSet
var set = new HashSet<int> { 1, 2, 2 };
Console.WriteLine(set.Count); // 2
77. Queue in C#
Enqueue/Dequeue/Peek are core operations.
Queue
var q = new Queue<string>();
q.Enqueue("job1");
var next = q.Dequeue();
78. Stack in C#
Useful for undo stacks and depth-first algorithms.
Stack
var st = new Stack<int>();
st.Push(1);
var top = st.Pop();
79. LINQ in C#
LINQ works over IEnumerable in-memory and IQueryable providers (EF).
LINQ method syntax
var adults = people.Where(p => p.Age >= 18).Select(p => p.Name).ToList();
80. LINQ Query Syntax in C#
Method syntax and query syntax compile to similar calls — pick readable style.
Query syntax
var q =
from p in people
where p.Age >= 18
orderby p.Name
select p.Name;
81. Lambda Expressions in C#
Captures close over variables — know closure lifetime implications.
Lambda
Func<int, int> square = x => x * x;
var evens = nums.Where(n => n % 2 == 0);
82. Delegates in C#
Delegates underpin events and callbacks.
Func/Action
Action<string> log = Console.WriteLine;
Func<int, int, int> add = (a, b) => a + b;
83. Events in C#
Always null-conditional invoke: Changed?.Invoke(…).
Event tip
public event EventHandler? Changed;
Changed?.Invoke(this, EventArgs.Empty);
84. Anonymous Methods in C#
Prefer lambda syntax in modern code.
Anonymous method tip
delegate(int x) { return x + 1; }
Today: x => x + 1
85. Extension Methods in C#
Keep extensions focused; don’t hide expensive operations.
Extension
static class StringExt
{
public static bool IsEmpty(this string? s) => string.IsNullOrEmpty(s);
}
86. Nullable Reference Types in C#
Treat warnings seriously — they prevent NullReferenceExceptions.
NRT tip
#nullable enable
string name = "Asha"; // non-null
string? nickname = null;
87. Exception Handling in C#
Don’t swallow exceptions; catch specific types when possible.
Exceptions tip
catch specific exceptions
use finally/using for cleanup
throw informative exceptions
avoid empty catch
88. try, catch, finally in C#
Prefer using for IDisposable instead of manual finally when possible.
try/catch
try
{
var text = File.ReadAllText(path);
}
catch (FileNotFoundException ex)
{
Console.Error.WriteLine(ex.Message);
}
89. throw and Custom Exceptions in C#
Don’t over-create custom exceptions — use existing BCL types when they fit.
Custom exception tip
class OrderNotFoundException : Exception
{
public OrderNotFoundException(string id) : base($"Order {id} not found") {}
}
90. File Handling in C#
Prefer async file APIs in web apps to avoid blocking threads.
File tip
File / FileInfo
StreamReader / StreamWriter
Path helpers
Async variants
91. Reading and Writing Files in C#
Handle IO exceptions and encoding explicitly when needed.
Read/Write
await File.WriteAllTextAsync("out.txt", content);
var text = await File.ReadAllTextAsync("out.txt");
92. JSON Handling in C#
Prefer System.Text.Json for new .NET apps unless you need Newtonsoft features.
System.Text.Json
var json = JsonSerializer.Serialize(user);
var copy = JsonSerializer.Deserialize<User>(json);
93. Serialization and Deserialization in C#
Validate deserialized data; don’t trust untrusted payloads.
Serialization tip
DTOs for boundaries
Ignore unexpected fields carefully
Version contracts
Never deserialize untrusted binary blindly
94. Date and Time in C#
Prefer DateTimeOffset / UTC for stored timestamps.
DateTime tip
var now = DateTimeOffset.UtcNow;
var local = now.ToLocalTime();
95. Regular Expressions in C#
Cache compiled regex for hot paths; prefer simple parsing when possible.
Regex
var ok = Regex.IsMatch(email, @"^[^@s]+@[^@s]+.[^@s]+$");
96. Async and Await in C#
Don’t block on async (.Result/Wait) in UI/ASP.NET — await instead.
async/await
async Task<string> LoadAsync(string url)
{
using var client = new HttpClient();
return await client.GetStringAsync(url);
}
97. Task and Task-Based Programming in C#
Pass CancellationToken through APIs for cooperative cancel.
Task tip
await Task.WhenAll(LoadAAsync(), LoadBAsync());
98. Multithreading in C#
Prefer Task Parallel Library / channels over manual threads when possible.
Concurrency tip
Tasks for async I/O
Parallel for CPU-bound
lock / concurrent collections
Avoid shared mutable state
99. Dependency Injection in C#
Depend on abstractions (interfaces) for testability.
DI tip
builder.Services.AddScoped<IUserService, UserService>();
// ctor: public HomeController(IUserService users) { }
100. Reflection in C#
Powerful but slower — use for frameworks/plugins, not hot loops.
Reflection tip
Type.GetType / GetMethods
Attributes discovery
Prefer source generators when possible
101. Attributes in C#
Examples: [HttpGet], [Required], [JsonPropertyName].
Attribute
public class CreateUserRequest
{
[Required]
public string Email { get; set; } = "";
}
102. Memory Management and Garbage Collection in C#
Managed memory is GC’d; unmanaged resources need Dispose/using.
GC tip
GC manages managed heap
Dispose unmanaged/native resources
using / await using
Avoid premature GC.Collect
103. C# with SQL Server
Always use parameterized queries — never concatenate untrusted SQL.
Parameterized tip
// Prefer EF Core or:
cmd.Parameters.AddWithValue("@id", id); // or better typed parameters
104. Entity Framework Core
Use migrations for schema changes and DbContext for unit-of-work style access.
DbContext idea
class AppDb : DbContext
{
public DbSet<User> Users => Set<User>();
}
105. CRUD with Entity Framework Core
Call SaveChanges/SaveChangesAsync after tracked changes.
CRUD sketch
db.Users.Add(new User { Email = email });
await db.SaveChangesAsync();
var user = await db.Users.FirstAsync(u => u.Email == email);
106. ASP.NET Core Introduction
Minimal hosting model + middleware pipeline are foundational.
ASP.NET Core pieces
WebApplication builder
Middleware pipeline
DI container
MVC / Minimal APIs / Razor
107. MVC Architecture in ASP.NET Core
Controllers handle HTTP; models hold data; views render UI.
MVC flow
Request → Controller
→ Model/services
→ View / response
108. ASP.NET Core Web API
Return proper status codes and problem details for errors.
API controller sketch
[ApiController]
[Route("api/[controller]")]
public class ItemsController : ControllerBase
{
[HttpGet]
public ActionResult<IEnumerable<Item>> Get() => Ok(items);
}
109. REST API Development with C#
Version APIs thoughtfully; keep DTOs separate from entities.
REST tip
GET/POST/PUT/PATCH/DELETE
DTO mapping
Validation
Consistent error shape
110. Authentication and Authorization in ASP.NET Core
Use ASP.NET Core Identity / JWT / policies based on app needs.
AuthZ tip
Authentication → who are you?
Authorization → what can you do?
Policies/roles/claims
111. JWT Authentication in ASP.NET Core
Store secrets securely; use HTTPS; keep token lifetimes short + refresh strategy.
JWT tip
Issue token on login
Authorization: Bearer <token>
Validate issuer/audience/lifetime
HTTPS only
112. Entity Framework Core with Web API
Use async EF methods; avoid lazy-loading surprises in APIs.
EF + API tip
AddDbContext
Scoped lifetime
Project to DTOs
AsNoTracking for read-only
113. API Documentation with Swagger in ASP.NET Core
Add annotations and examples for better client experience.
Swagger tip
AddSwaggerGen
Map OpenAPI endpoints
Document auth schemes
Keep DTOs accurate
114. Unit Testing with xUnit
Test domain logic fast; use WebApplicationFactory for integration tests.
xUnit tip
[Fact]
public void Add_works()
{
Assert.Equal(5, Add(2, 3));
}
115. Debugging C# Applications
Reproduce first; use conditional breakpoints for noisy loops.
Debug tip
Breakpoints / step
Call stack
Exception settings
Logs + correlation IDs
116. Logging in .NET
Log warnings/errors with context; avoid logging secrets.
ILogger tip
_logger.LogInformation("Created user {UserId}", user.Id);
117. Git and GitHub for C# Projects
Use branches/PRs; never commit secrets or user secrets store carelessly.
Git tip
dotnet new gitignore
Commit .csproj not bin/obj
PR reviews
Protect main branch
118. C# Security Best Practices
Enable nullable reference types; follow OWASP-minded API habits.
Security checklist
Parameterized queries / EF
HTTPS + secure cookies
AuthZ on every endpoint
Secrets in vault/user-secrets
Validate DTOs
Dependency updates
119. C# Interview Questions
Be ready for value vs reference, async/await, DI, LINQ, and boxing.
Sample Q&A
Q: Interface vs abstract class?
A: Interfaces = contracts (multi); abstract class = shared base + optional impl.
Q: async void?
A: Avoid except event handlers.
Q: IEnumerable vs IQueryable?
A: In-memory vs provider query translation (e.g. EF).
120. Real-World C# Project
Include README, .gitignore, and sample requests.
Project ideas
Task manager Web API
Inventory API + EF Core
Blog API with JWT
File processing worker service
Minimal API + Swagger demo
121. Final Project – Complete ASP.NET Core Application
Ship a production-shaped solution: domain models, EF Core + migrations, REST API, JWT (or Identity) auth, validation, Swagger, logging, unit tests, and README with run instructions.
- Design solution layers and domain.
- Implement EF Core + API CRUD.
- Add auth, Swagger, and tests.
- Document and demo the running app.
Final project scope
1. Solution structure (API + Domain + Data + Tests)
2. EF Core models + migrations
3. CRUD endpoints + DTOs
4. Validation + problem details
5. JWT/Identity auth on protected routes
6. Swagger docs
7. ILogger usage
8. xUnit tests for core logic/API
9. README + .env/user-secrets notes
Suggested features
Users/auth
Items/orders (or posts/comments)
Pagination/filtering
Seed data
Conclusion
You now have a full C# path: language mastery, .NET libraries, data access with EF Core, and ASP.NET Core APIs. Finish the final ASP.NET Core application project to turn the lessons into a portfolio-ready system.