DEV Community

Cover image for C# by Example – Great for Programmers Switching from Other Languages
Neeraj Sharma
Neeraj Sharma

Posted on • Edited on

C# by Example – Great for Programmers Switching from Other Languages

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!");
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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.";
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
};
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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 };
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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!");
    }
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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 };
Enter fullscreen mode Exit fullscreen mode

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}");
Enter fullscreen mode Exit fullscreen mode

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!");
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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}");
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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();
}
Enter fullscreen mode Exit fullscreen mode

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");
}
Enter fullscreen mode Exit fullscreen mode

Best Practices Demonstrated

  1. Consistent Naming: Use PascalCase for public members, camelCase for private members
  2. Proper Disposal: Always dispose resources using using statements
  3. Async All the Way: Don't mix synchronous and asynchronous code
  4. Exception Handling: Catch specific exceptions before general ones
  5. Null Safety: Check for null values before using objects
  6. LINQ Efficiency: Filter early to reduce dataset size
  7. Generic Constraints: Use appropriate constraints for type safety
  8. 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.

Additional Resources

Top comments (0)