C# Programming Language Guide — .NET Development Fundamentals
C# is a modern, type-safe, object-oriented language from Microsoft that runs on the .NET runtime, combining the power of C++ with the simplicity of Visual Basic for building Windows, web, and cloud applications.
What You’ll Learn
- The .NET framework and runtime
- LINQ for querying collections
- Async/await for asynchronous programming
- Properties, delegates, events, and generics
- NuGet package management
Why It Matters
C# is the primary language for the Microsoft ecosystem — Windows desktop apps with WPF/WinForms, web applications with ASP.NET, cloud services on Azure, and cross-platform apps with .NET MAUI or Unity game development. DodaZIP uses C# for its Windows shell integration and file context menu handlers. With .NET Core’s cross-platform support, C# now runs natively on Linux and macOS.
Learning Path
flowchart LR
A[C# Basics<br/>You are here] --> B[OOP & Properties]
B --> C[LINQ & Delegates]
C --> D[Async/Await]
D --> E[Build a Web API]
Your First C# Program
C# programs begin in a class with a Main method. The Console class provides input/output.
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, C#!");
}
}dotnet new console -n HelloCSharp
cd HelloCSharp
dotnet run
# Hello, C#!Properties and Auto-Properties
Properties encapsulate fields with get/set accessors.
using System;
class Person
{
public string Name { get; set; } // auto-property
public int Age { get; private set; } // read-only outside class
public Person(string name, int age)
{
Name = name;
Age = age;
}
public string Greeting => $"Hi, I'm {Name} and I'm {Age} years old.";
}
class Program
{
static void Main()
{
var person = new Person("Alice", 30);
Console.WriteLine(person.Greeting);
// Hi, I'm Alice and I'm 30 years old.
}
}Delegates and Events
Delegates are type-safe function pointers. Events build on delegates for publish-subscribe patterns.
using System;
// Delegate declaration
delegate void Notify(string message);
class Publisher
{
public event Notify OnNotify;
public void RaiseEvent(string msg)
{
OnNotify?.Invoke(msg); // null-conditional invoke
}
}
class Program
{
static void Handler(string msg)
{
Console.WriteLine($"Received: {msg}");
}
static void Main()
{
var pub = new Publisher();
pub.OnNotify += Handler;
pub.RaiseEvent("Hello from C# events!");
// Received: Hello from C# events!
}
}LINQ — Language Integrated Query
LINQ lets you query collections using SQL-like syntax or method chains.
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
var numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Query syntax
var evenNumbers = from n in numbers
where n % 2 == 0
select n * n;
Console.WriteLine(string.Join(", ", evenNumbers));
// 4, 16, 36, 64, 100
// Method syntax
var result = numbers
.Where(n => n > 5)
.OrderByDescending(n => n)
.Select(n => n * 10);
Console.WriteLine(string.Join(", ", result));
// 100, 90, 80, 70, 60
}
}Async and Await
Async/await provides clean asynchronous programming without callback hell.
using System;
using System.Net.Http;
using System.Threading.Tasks;
class Program
{
static async Task Main(string[] args)
{
var content = await FetchUrlAsync("https://example.com");
Console.WriteLine($"Received {content.Length} characters");
}
static async Task<string> FetchUrlAsync(string url)
{
using var client = new HttpClient();
var result = await client.GetStringAsync(url);
return result;
}
}Generics
Generics create type-safe, reusable code without boxing or casting.
using System;
using System.Collections.Generic;
class Repository<T>
{
private List<T> items = new List<T>();
public void Add(T item) => items.Add(item);
public T Get(int index) => items[index];
public int Count => items.Count;
}
class Program
{
static void Main()
{
var intRepo = new Repository<int>();
intRepo.Add(10);
intRepo.Add(20);
Console.WriteLine(intRepo.Get(1)); // 20
var stringRepo = new Repository<string>();
stringRepo.Add("Hello");
stringRepo.Add("World");
Console.WriteLine(stringRepo.Get(0)); // Hello
}
}NuGet Package Manager
NuGet is the .NET package manager. It integrates with the .NET CLI:
dotnet add package Newtonsoft.Json
# Adding package 'Newtonsoft.Json' to projectusing System;
using Newtonsoft.Json;
class Program
{
static void Main()
{
var data = new { Name = "Alice", Age = 30 };
string json = JsonConvert.SerializeObject(data);
Console.WriteLine(json);
// {"Name":"Alice","Age":30}
var deserialized = JsonConvert.DeserializeAnonymousType(
json, new { Name = "", Age = 0 }
);
Console.WriteLine(deserialized.Name); // Alice
}
}Common Mistakes
1. Confusing == with .Equals() for strings
Both work for strings in C# (unlike Java) because == is overridden for string. But for custom classes, == checks reference equality unless overridden.
2. Forgetting await in async methods
var result = FetchUrlAsync(url); // returns Task, not the result!
var result = await FetchUrlAsync(url); // correct3. Using var when type is unclear
var is fine when the type is obvious (var x = new List<int>()). Avoid it when it obscures readability (var x = GetData()).
4. Not disposing of IDisposable resources
Use using statements to ensure file handles, database connections, and network streams are properly closed.
5. Boxing value types unnecessarily
int x = 42;
object o = x; // boxing — allocates on heapUse generics to avoid boxing in collections.
6. NullReferenceException with uninitialized objects
Check for null with the ?. (null-conditional) and ?? (null-coalescing) operators.
Practice Questions
What is the difference between
classandstructin C#? A class is a reference type (allocated on heap, passed by reference). A struct is a value type (allocated on stack, copied on assignment).What does LINQ stand for? Language Integrated Query. It provides query capabilities directly in C# syntax.
What is the purpose of
asyncandawait? They simplify asynchronous programming by letting you write async code that looks synchronous. The compiler handles the complexity of continuations.What is NuGet? The package manager for .NET. It hosts hundreds of thousands of libraries and integrates with Visual Studio and the .NET CLI.
How does garbage collection work in .NET? The GC automatically reclaims memory for unreferenced objects. It uses generational collection — short-lived objects (Gen 0) are collected frequently; long-lived objects (Gen 2) less so.
Challenge: Write a C# console application that reads a CSV file, parses it into objects using LINQ, and outputs summary statistics.
Mini Project — Task Manager with Async Logging
Build a simple task manager that processes tasks in parallel with async logging.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
class TaskManager
{
private readonly string logFile;
public TaskManager(string logFile)
{
this.logFile = logFile;
}
private async Task LogAsync(string message)
{
using var writer = new StreamWriter(logFile, append: true);
await writer.WriteLineAsync($"[{DateTime.Now:T}] {message}");
}
public async Task ProcessTasksAsync(IEnumerable<string> tasks)
{
var taskList = new List<Task>();
foreach (var task in tasks)
{
taskList.Add(ProcessOneAsync(task));
}
await Task.WhenAll(taskList);
await LogAsync("All tasks completed");
}
private async Task ProcessOneAsync(string taskName)
{
await LogAsync($"Starting: {taskName}");
await Task.Delay(1000); // simulate work
await LogAsync($"Completed: {taskName}");
}
}
class Program
{
static async Task Main()
{
var manager = new TaskManager("tasks.log");
var tasks = new[] { "Scan files", "Compress archive", "Send report" };
await manager.ProcessTasksAsync(tasks);
Console.WriteLine("Done. Check tasks.log for details.");
}
}FAQ
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro