C# Language Reference

Introduction to C#

C# is a modern, object-oriented, and type-safe programming language developed by Microsoft. It combines the power of C++ with the ease of use of Visual Basic, offering a robust platform for building a wide range of applications, from web services to desktop applications and mobile apps.

This documentation provides a comprehensive overview of the C# language, its features, syntax, and best practices.

C# Language Basics

C# is a statically-typed language, meaning variable types are checked at compile time. It supports a rich set of data types and control flow structures.

Variables and Data Types

C# offers built-in data types like int, float, double, bool, char, and string. You can also define your own custom types using classes and structs.

int count = 10;
string message = "Hello, C#!";
bool isComplete = true;

Control Flow Statements

Use if, else, switch, for, while, and foreach to control the execution flow of your programs.

if (count > 5) {
    // Do something
} else {
    // Do something else
}

for (int i = 0; i < count; i++) {
    // Loop iterations
}

Types in C#

C# distinguishes between value types and reference types, impacting how data is stored and passed.

Value Types

Value types directly contain their data. When you assign a value type variable to another, the value is copied.

  • Primitive Types: int, float, double, bool, char, struct.
  • Structs: User-defined types that can hold data and methods, but behave like primitive types.

Reference Types

Reference types store a reference to the object's location in memory. When you assign a reference type variable, only the reference is copied, not the object itself.

  • Classes: The fundamental building blocks of object-oriented programming.
  • Interfaces: Contracts that define a set of members a class must implement.
  • Delegates: Type-safe function pointers.
  • Arrays: Collections of elements of the same type.
  • Strings: Immutable sequences of characters.

Classes and Structs

Classes and structs are used to define custom types in C#. Classes support inheritance and polymorphism, making them suitable for complex object models. Structs are lightweight and are often used for small data structures.

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

    public void Greet() {
        Console.WriteLine($"Hello, my name is {Name} and I am {Age} years old.");
    }
}

public struct Point {
    public int X;
    public int Y;
}

Interfaces

Interfaces define a contract. Any class that implements an interface must provide implementations for all the members declared in the interface.

public interface IDrawable {
    void Draw();
}

public class Circle : IDrawable {
    public void Draw() {
        Console.WriteLine("Drawing a circle.");
    }
}

Inheritance and Polymorphism

C# supports single inheritance for classes, but multiple inheritance for interfaces. Polymorphism allows objects of different classes to be treated as objects of a common base class.

public class Animal {
    public virtual void MakeSound() {
        Console.WriteLine("Generic animal sound");
    }
}

public class Dog : Animal {
    public override void MakeSound() {
        Console.WriteLine("Woof!");
    }
}

// Usage
Animal myDog = new Dog();
myDog.MakeSound(); // Output: Woof!

Generics

Generics allow you to define classes, interfaces, methods, and delegates that operate on types specified as parameters. This promotes code reusability and type safety.

public class Box {
    public T Content { get; set; }
}

// Usage
Box intBox = new Box { Content = 123 };
Box stringBox = new Box { Content = "Hello" };

Delegates and Events

Delegates are type-safe function pointers that enable callback mechanisms. Events are a mechanism for a class to provide notifications to other classes or objects when a change occurs.

public delegate void MyEventHandler(object sender, EventArgs e);

public class Publisher {
    public event MyEventHandler MyEvent;

    protected virtual void OnMyEvent(EventArgs e) {
        MyEvent?.Invoke(this, e);
    }

    public void DoSomething() {
        // ...
        OnMyEvent(EventArgs.Empty);
    }
}

Asynchronous Programming

C# provides powerful features for asynchronous programming using async and await keywords, which simplify writing non-blocking code for I/O-bound and CPU-bound operations.

public async Task DownloadDataAsync(string url) {
    using (var client = new HttpClient()) {
        var response = await client.GetAsync(url);
        response.EnsureSuccessStatusCode();
        var content = await response.Content.ReadAsStringAsync();
        Console.WriteLine($"Downloaded {content.Length} bytes.");
    }
}

Language Integrated Query (LINQ)

LINQ provides a consistent syntax for querying data from various sources, such as collections, databases, and XML documents.

var numbers = new List { 5, 10, 15, 20 };
var greaterThanTen = from num in numbers
                     where num > 10
                     select num;

foreach (var n in greaterThanTen) {
    Console.WriteLine(n); // Output: 15, 20
}

Error Handling

C# uses exceptions for error handling. The try, catch, and finally blocks are used to manage and respond to runtime errors.

try {
    // Code that might throw an exception
    int result = 10 / 0;
} catch (DivideByZeroException ex) {
    Console.WriteLine("Error: Cannot divide by zero.");
} finally {
    // Cleanup code
    Console.WriteLine("Finally block executed.");
}

Advanced Features

Explore other powerful features like:

  • Extension Methods: Add new methods to existing types without modifying their source code.
  • Lambda Expressions: Concise syntax for anonymous functions.
  • Pattern Matching: Powerful syntax for checking and extracting data from objects.
  • Records: Immutable data types designed for data-centric scenarios.
  • Nullable Reference Types: Help reduce null reference exceptions at compile time.