C# Fundamentals Code Samples
Overview
This document contains key code samples from each topic in Section 1: C# Fundamentals. These examples demonstrate best practices and common patterns you'll encounter throughout your C# development journey.
1. Introduction and Environment Setup
Basic Console Application
// Program.cs - Modern minimal template (C# 9+)
Console.WriteLine("Hello, World!");
// Traditional console application structure
using System;
namespace MyFirstApp
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
}
}
}
Project File Configuration
<!-- MyFirstCSharpApp.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
2. Variables, Data Types, and Operators
Variable Declarations
// Basic data types
int age = 25;
string name = "John";
bool isStudent = true;
double salary = 50000.50;
decimal accountBalance = 1250.75m;
char grade = 'A';
// Implicit typing
var count = 100; // int
var message = "Hello"; // string
var price = 99.99; // double
// Nullable types
int? nullableAge = null;
double? nullableScore = 85.5;
// String interpolation
string greeting = $"Hello, {name}! You are {age} years old.";
Operators
// Arithmetic operators
int sum = 10 + 5;
int difference = 10 - 5;
int product = 10 * 5;
int quotient = 10 / 5;
int remainder = 10 % 3;
// Assignment operators
int x = 10;
x += 5; // x = x + 5
x -= 3; // x = x - 3
x *= 2; // x = x * 2
// Comparison operators
bool isEqual = (10 == 5);
bool isGreater = (10 > 5);
bool isLessOrEqual = (10 <= 5);
// Logical operators
bool result = (true && false); // false
bool result2 = (true || false); // true
bool result3 = !true; // false
3. Control Flow Statements
Conditional Statements
// if-else statement
int score = 85;
if (score >= 90)
{
Console.WriteLine("Grade: A");
}
else if (score >= 80)
{
Console.WriteLine("Grade: B");
}
else
{
Console.WriteLine("Grade: C");
}
// switch statement
int dayOfWeek = 3;
switch (dayOfWeek)
{
case 1:
Console.WriteLine("Monday");
break;
case 2:
Console.WriteLine("Tuesday");
break;
case 3:
Console.WriteLine("Wednesday");
break;
default:
Console.WriteLine("Other day");
break;
}
// Switch expression (C# 8+)
string dayName = dayOfWeek switch
{
1 => "Monday",
2 => "Tuesday",
3 => "Wednesday",
_ => "Other day"
};
Looping Statements
// for loop
for (int i = 0; i < 10; i++)
{
Console.WriteLine($"Number: {i}");
}
// foreach loop
string[] fruits = { "Apple", "Banana", "Orange" };
foreach (string fruit in fruits)
{
Console.WriteLine($"Fruit: {fruit}");
}
// while loop
int counter = 0;
while (counter < 5)
{
Console.WriteLine($"Count: {counter}");
counter++;
}
// do-while loop
int number = 0;
do
{
Console.WriteLine($"Number: {number}");
number++;
} while (number < 3);
4. Methods and Functions
Method Declaration and Usage
// Method with parameters and return value
public static int Add(int a, int b)
{
return a + b;
}
// Void method
public static void GreetUser(string name)
{
Console.WriteLine($"Hello, {name}!");
}
// Method with optional parameters
public static void CreateFile(string name, string extension = ".txt", bool overwrite = false)
{
string fileName = $"{name}{extension}";
Console.WriteLine($"Creating file: {fileName}, Overwrite: {overwrite}");
}
// Expression-bodied method (C# 6+)
public static int Square(int number) => number * number;
public static void SayHello(string name) => Console.WriteLine($"Hello, {name}!");
// Method with out parameter
public static bool TryParseInt(string input, out int result)
{
return int.TryParse(input, out result);
}
// Method with params
public static int SumNumbers(params int[] numbers)
{
int sum = 0;
foreach (int number in numbers)
{
sum += number;
}
return sum;
}
5. Arrays and Collections
Arrays
// Array declaration and initialization
int[] numbers = new int[5];
int[] scores = { 95, 87, 92, 88, 90 };
string[] names = new string[] { "John", "Jane", "Bob" };
// Multi-dimensional arrays
int[,] matrix = new int[3, 3];
int[,] predefinedMatrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
// Jagged arrays
int[][] jaggedArray = new int[3][];
jaggedArray[0] = new int[] { 1, 2 };
jaggedArray[1] = new int[] { 3, 4, 5 };
jaggedArray[2] = new int[] { 6 };
Collections
// List<T>
List<string> names = new List<string>();
names.Add("John");
names.Add("Jane");
names.AddRange(new[] { "Bob", "Alice" });
// Dictionary<TKey, TValue>
Dictionary<string, int> ages = new Dictionary<string, int>();
ages["John"] = 25;
ages.Add("Jane", 30);
// HashSet<T>
HashSet<string> uniqueNames = new HashSet<string>();
uniqueNames.Add("John");
uniqueNames.Add("Jane");
uniqueNames.Add("John"); // Won't be added (duplicate)
// Stack<T>
Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
int top = stack.Pop();
// Queue<T>
Queue<string> queue = new Queue<string>();
queue.Enqueue("First");
queue.Enqueue("Second");
string first = queue.Dequeue();
6. Object-Oriented Programming Basics
Classes and Objects
public class Person
{
// Properties
public string Name { get; set; }
public int Age { get; set; }
// Constructor
public Person(string name, int age)
{
Name = name;
Age = age;
}
// Method
public void SayHello()
{
Console.WriteLine($"Hello, my name is {Name}");
}
}
// Usage
Person person = new Person("John", 25);
person.SayHello();
Inheritance
// Base class
public class Animal
{
public string Name { get; set; }
public virtual void MakeSound()
{
Console.WriteLine("The animal makes a sound");
}
}
// Derived class
public class Dog : Animal
{
public string Breed { get; set; }
public override void MakeSound()
{
Console.WriteLine($"{Name} barks: Woof! Woof!");
}
}
Encapsulation
public class BankAccount
{
private decimal balance;
private string accountNumber;
public string AccountNumber => accountNumber;
public decimal Balance => balance;
public void Deposit(decimal amount)
{
if (amount > 0)
{
balance += amount;
}
}
public bool Withdraw(decimal amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
return true;
}
return false;
}
}
7. Exception Handling
Basic Exception Handling
try
{
int result = 10 / 0;
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero!");
}
catch (Exception ex)
{
Console.WriteLine($"An error occurred: {ex.Message}");
}
finally
{
Console.WriteLine("This always executes");
}
Custom Exceptions
public class InsufficientFundsException : Exception
{
public decimal Balance { get; }
public decimal Amount { get; }
public InsufficientFundsException(decimal balance, decimal amount)
: base($"Insufficient funds. Balance: ${balance}, Attempted withdrawal: ${amount}")
{
Balance = balance;
Amount = amount;
}
}
8. File I/O Operations
Reading Files
// Read all text
string content = await File.ReadAllTextAsync("data.txt");
// Read all lines
string[] lines = await File.ReadAllLinesAsync("data.txt");
// Using StreamReader
using (StreamReader reader = new StreamReader("data.txt"))
{
string line;
while ((line = await reader.ReadLineAsync()) != null)
{
Console.WriteLine(line);
}
}
Writing Files
// Write all text
await File.WriteAllTextAsync("output.txt", "Hello, World!");
// Append text
await File.AppendAllTextAsync("output.txt", "\nAppended line");
// Using StreamWriter
using (StreamWriter writer = new StreamWriter("output.txt"))
{
await writer.WriteLineAsync("First line");
await writer.WriteLineAsync("Second line");
}
9. LINQ (Language Integrated Query)
Basic LINQ Operations
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// Filtering
var evenNumbers = numbers.Where(n => n % 2 == 0);
// Projection
var squares = numbers.Select(n => n * n);
// Sorting
var sorted = numbers.OrderByDescending(n => n);
// Aggregation
int sum = numbers.Sum();
double average = numbers.Average();
int max = numbers.Max();
// Complex query
var result = numbers
.Where(n => n > 5)
.Select(n => n * 2)
.OrderBy(n => n)
.ToList();
Grouping and Joining
// Grouping
var grouped = numbers.GroupBy(n => n % 2 == 0 ? "Even" : "Odd");
// Joining
List<Customer> customers = new List<Customer>();
List<Order> orders = new List<Order>();
var customerOrders = from customer in customers
join order in orders on customer.Id equals order.CustomerId
select new { CustomerName = customer.Name, OrderAmount = order.Amount };
10. Delegates and Events
Delegates
// Delegate declaration
public delegate void MessageHandler(string message);
// Using built-in delegates
Action<string> action = message => Console.WriteLine(message);
Func<int, int, int> add = (a, b) => a + b;
Predicate<int> isEven = number => number % 2 == 0;
// Multicast delegate
Action<string> multiHandler = message => Console.WriteLine($"Handler 1: {message}");
multiHandler += message => Console.WriteLine($"Handler 2: {message}");
Events
public class Button
{
public event EventHandler Clicked;
public void Click()
{
Clicked?.Invoke(this, EventArgs.Empty);
}
}
// Subscribing to events
Button button = new Button();
button.Clicked += (sender, e) => Console.WriteLine("Button clicked!");
11. Generics
Generic Classes and Methods
// Generic class
public class Container<T>
{
private T value;
public Container(T initialValue)
{
value = initialValue;
}
public T GetValue() => value;
public void SetValue(T newValue) => value = newValue;
}
// Generic method
public static T GetDefault<T>()
{
return default(T);
}
// Generic constraints
public class Calculator<T> where T : struct, IEquatable<T>, IComparable<T>
{
public bool AreEqual(T first, T second) => first.Equals(second);
}
12. Asynchronous Programming
Async/Await Pattern
// Async method
public async Task<string> GetDataAsync()
{
await Task.Delay(1000); // Simulate async work
return "Data retrieved";
}
// Async method with return value
public async Task<int> GetNumberAsync()
{
await Task.Delay(500);
return 42;
}
// Calling async methods
public async Task Example()
{
string data = await GetDataAsync();
int number = await GetNumberAsync();
Console.WriteLine($"Data: {data}, Number: {number}");
}
Concurrent Operations
// Running tasks in parallel
public async Task RunTasksInParallelAsync()
{
Task<int> task1 = GetNumberAsync();
Task<int> task2 = GetNumberAsync();
Task<int> task3 = GetNumberAsync();
int[] results = await Task.WhenAll(task1, task2, task3);
}
// Processing first completed task
public async Task ProcessFirstCompletedAsync()
{
Task<string> fastTask = Task.FromResult("Fast result");
Task<string> slowTask = Task.Run(async () =>
{
await Task.Delay(2000);
return "Slow result";
});
Task<string> completedTask = await Task.WhenAny(fastTask, slowTask);
string result = await completedTask;
}
13. Memory Management
IDisposable Pattern
public class ResourceManager : IDisposable
{
private bool disposed = false;
private FileStream fileStream;
public ResourceManager(string filePath)
{
fileStream = new FileStream(filePath, FileMode.Open);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
fileStream?.Dispose();
}
disposed = true;
}
}
}
Using Statements
// Traditional using statement
using (var fileStream = new FileStream("data.txt", FileMode.Open))
{
// Work with fileStream
} // Automatically disposed
// C# 8+ using declaration
using var fileStream = new FileStream("data.txt", FileMode.Open);
// Work with fileStream
// Automatically disposed at end of scope
14. Debugging Techniques
Debugging Attributes
using System.Diagnostics;
[DebuggerDisplay("Person: {Name} (Age: {Age})")]
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
[DebuggerStepThrough]
public static string FormatString(string input)
{
return input?.Trim().ToUpper();
}
Conditional Compilation
[Conditional("DEBUG")]
public static void Log(string message)
{
Console.WriteLine($"[DEBUG] {DateTime.Now}: {message}");
}
public void ProcessData()
{
Log("Starting data processing");
// Process data
Log("Data processing completed");
}
Best Practices Demonstrated
- Consistent Naming: Use PascalCase for public members, camelCase for private members
- Proper Disposal: Always dispose resources using using statements
- Async All the Way: Don't mix synchronous and asynchronous code
- Exception Handling: Catch specific exceptions before general ones
- Null Safety: Check for null values before using objects
- LINQ Efficiency: Filter early to reduce dataset size
- Generic Constraints: Use appropriate constraints for type safety
- Method Organization: Keep methods small and focused on single responsibilities
Next Steps
These code samples provide a foundation for understanding C# fundamentals. As you progress through the course, you'll build upon these concepts to create more complex applications. Refer back to these examples when you need a quick reminder of syntax or patterns.
Top comments (0)