Introduction to C#
Welcome to the comprehensive C# tutorial! C# (pronounced "C-sharp") is a modern, object-oriented, and type-safe programming language developed by Microsoft. It is widely used for building a variety of applications, including desktop applications, web applications (using ASP.NET), mobile apps (with Xamarin/MAUI), games (with Unity), and cloud services.
What is C#?
C# is part of the .NET framework and is designed for building robust, scalable, and high-performance applications. It combines the power and flexibility of C++ with the ease of development of Visual Basic. C# is a versatile language that supports various programming paradigms, including object-oriented, component-oriented, and functional programming.
Setting Up Your Development Environment
To start coding in C#, you'll need an Integrated Development Environment (IDE). The most popular choice is **Visual Studio**, also developed by Microsoft.
- Download Visual Studio: Go to the Visual Studio website and download the Community edition (which is free for individual developers, open-source projects, and academic use).
- Install Workloads: During installation, select the workloads relevant to what you want to build (e.g., "ASP.NET and web development," "Desktop development with .NET," "Game development with Unity").
- Launch Visual Studio: Once installed, open Visual Studio and you're ready to create your first C# project!
Your First C# Program: "Hello, World!"
Let's write the classic "Hello, World!" program in C#. This will help you understand the basic structure of a C# application.
using System; // Imports the System namespace, which contains fundamental classes and base types
namespace HelloWorldApp // Declares a namespace to organize your code
{
class Program // Declares a class, which is a blueprint for creating objects
{
static void Main(string[] args) // The entry point of your application
{
Console.WriteLine("Hello, World!"); // Prints "Hello, World!" to the console
Console.ReadKey(); // Keeps the console window open until a key is pressed (for console apps)
}
}
}
Explanation:
using System;
: This line imports the `System` namespace, which provides access to fundamental classes and types, such as `Console` for input/output operations.namespace HelloWorldApp
: Namespaces are used to organize code and avoid naming conflicts.class Program
: C# is an object-oriented language, and all code resides within classes.static void Main(string[] args)
: This is the main method, the entry point of every C# console application. When you run the program, execution begins here.Console.WriteLine("Hello, World!");
: This line uses the `WriteLine` method from the `Console` class to print the string "Hello, World!" to the console.Console.ReadKey();
: This line is often used in console applications to prevent the console window from closing immediately after execution, allowing you to see the output.
C# Fundamentals
Variables and Data Types
Variables are containers for storing data values. In C#, every variable must have a specified data type.
// Integer types
int age = 30; // Stores whole numbers
long bigNumber = 123456789012345L; // Stores larger whole numbers
// Floating-point types
float price = 19.99f; // Stores fractional numbers (single precision)
double temperature = 25.5; // Stores fractional numbers (double precision, more common)
// Character and String types
char initial = 'J'; // Stores a single character
string name = "John Doe"; // Stores a sequence of characters
// Boolean type
bool isActive = true; // Stores true or false values
Common data types include `int`, `double`, `bool`, `char`, and `string`.
Operators
Operators are symbols that perform operations on variables and values.
- **Arithmetic Operators:** `+`, `-`, `*`, `/`, `%` (modulus)
- **Assignment Operators:** `=`, `+=`, `-=`, `*=` etc.
- **Comparison Operators:** `==` (equal to), `!=` (not equal), `>`, `<`, `>=`, `<=`
- **Logical Operators:** `&&` (AND), `||` (OR), `!` (NOT)
int a = 10;
int b = 5;
Console.WriteLine(a + b); // Addition: 15
Console.WriteLine(a - b); // Subtraction: 5
Console.WriteLine(a * b); // Multiplication: 50
Console.WriteLine(a / b); // Division: 2
Console.WriteLine(a % b); // Modulus: 0
bool isGreater = (a > b); // Comparison: true
bool logicalAnd = (a > 0 && b > 0); // Logical AND: true
Control Flow
Control flow statements allow you to execute different blocks of code based on conditions or to repeat code.
If-Else Statements
int score = 75;
if (score >= 60)
{
Console.WriteLine("Passed");
}
else
{
Console.WriteLine("Failed");
}
Switch Statements
string day = "Monday";
switch (day)
{
case "Monday":
Console.WriteLine("Start of the week.");
break;
case "Friday":
Console.WriteLine("End of the week.");
break;
default:
Console.WriteLine("Mid-week.");
break;
}
Loops (for, while, foreach)
// For loop
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"For loop iteration: {i}");
}
// While loop
int count = 0;
while (count < 3)
{
Console.WriteLine($"While loop iteration: {count}");
count++;
}
// Foreach loop (for collections)
string[] fruits = { "Apple", "Banana", "Cherry" };
foreach (string fruit in fruits)
{
Console.WriteLine($"Fruit: {fruit}");
}
Methods
Methods (also known as functions) are blocks of code that perform a specific task. They help organize code and promote reusability.
class Calculator
{
// Method that returns a value
public int Add(int num1, int num2)
{
return num1 + num2;
}
// Method that doesn't return a value (void)
public void Greet(string name)
{
Console.WriteLine($"Hello, {name}!");
}
}
// How to use methods
// Calculator calc = new Calculator();
// int sum = calc.Add(10, 20);
// Console.WriteLine($"Sum: {sum}"); // Output: Sum: 30
// calc.Greet("Alice"); // Output: Hello, Alice!
Object-Oriented Programming (OOP) in C#
C# is a strongly object-oriented language. OOP is a programming paradigm based on the concept of "objects", which can contain data and code. The main principles of OOP are:
Classes and Objects
A **class** is a blueprint or a template for creating objects. An **object** is an instance of a class.
// Class definition
class Car
{
// Properties (data)
public string Model { get; set; }
public string Color { get; set; }
public int Year { get; set; }
// Method (behavior)
public void Drive()
{
Console.WriteLine($"{Model} is driving.");
}
}
// Creating objects (instances of the Car class)
// Car myCar = new Car();
// myCar.Model = "Toyota";
// myCar.Color = "Blue";
// myCar.Year = 2023;
// myCar.Drive(); // Output: Toyota is driving.
Inheritance
Inheritance allows a class (child/derived class) to inherit properties and methods from another class (parent/base class). This promotes code reusability.
class Vehicle // Base class
{
public string Brand { get; set; }
public void Honk()
{
Console.WriteLine("Tuut, tuut!");
}
}
class Bicycle : Vehicle // Derived class inheriting from Vehicle
{
public int NumberOfGears { get; set; }
}
// Usage:
// Bicycle myBicycle = new Bicycle();
// myBicycle.Brand = "Giant"; // Inherited from Vehicle
// myBicycle.NumberOfGears = 21;
// myBicycle.Honk(); // Inherited method
Polymorphism
Polymorphism means "many forms." It allows objects of different classes to be treated as objects of a common base class. This is often achieved through method overriding.
class Animal
{
public virtual void MakeSound() // Virtual method can be overridden
{
Console.WriteLine("The animal makes a sound");
}
}
class Dog : Animal
{
public override void MakeSound() // Overriding the base method
{
Console.WriteLine("The dog barks");
}
}
class Cat : Animal
{
public override void MakeSound() // Overriding the base method
{
Console.WriteLine("The cat meows");
}
}
// Usage:
// Animal myAnimal = new Animal();
// Animal myDog = new Dog();
// Animal myCat = new Cat();
// myAnimal.MakeSound(); // Output: The animal makes a sound
// myDog.MakeSound(); // Output: The dog barks
// myCat.MakeSound(); // Output: The cat meows
Encapsulation
Encapsulation is the bundling of data (attributes) and methods that operate on the data into a single unit (class), and restricting direct access to some of an object's components. This is achieved using access modifiers (e.g., `public`, `private`, `protected`).
class BankAccount
{
private double _balance; // Private field, not directly accessible from outside
public BankAccount(double initialBalance)
{
_balance = initialBalance;
}
public void Deposit(double amount) // Public method to modify balance
{
if (amount > 0)
{
_balance += amount;
Console.WriteLine($"Deposited: {amount}. New balance: {_balance}");
}
}
public double GetBalance() // Public method to access balance
{
return _balance;
}
}
// Usage:
// BankAccount account = new BankAccount(1000);
// account.Deposit(500);
// Console.WriteLine($"Current balance: {account.GetBalance()}");
// // account._balance = 0; // This would cause a compile-time error due to private access
Abstraction
Abstraction means hiding the complex implementation details and showing only the essential features of the object. This can be achieved using abstract classes and interfaces.
// Abstract class
public abstract class Shape
{
public abstract double GetArea(); // Abstract method (no implementation)
public void Display()
{
Console.WriteLine("This is a shape.");
}
}
// Concrete class inheriting from abstract class
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public override double GetArea() // Must implement abstract method
{
return Math.PI * Radius * Radius;
}
}
// Usage:
// Circle circle = new Circle(5);
// Console.WriteLine($"Area of Circle: {circle.GetArea()}");
// circle.Display();
Understanding .NET
C# is tightly integrated with the .NET platform. .NET is a free, cross-platform, open-source developer platform for building many different types of applications.
What is .NET?
.NET is an ecosystem that provides a runtime environment, a vast class library, and language interoperability. It allows developers to write code in multiple languages (like C#, F#, VB.NET) that can run on various operating systems.
.NET Framework vs. .NET (Core)
- **.NET Framework:** The original implementation of .NET, primarily for Windows desktop and web applications (ASP.NET). It is Windows-specific.
- **.NET (formerly .NET Core):** A cross-platform, open-source, and modular redesign of .NET. It supports Windows, macOS, and Linux, and is the future of the .NET platform. New applications should generally target .NET.
Common Language Runtime (CLR)
The CLR is the virtual machine component of the .NET platform. It manages the execution of .NET programs. Key functions of the CLR include:
- **Just-In-Time (JIT) Compilation:** Converts compiled intermediate language (IL) code into native machine code at runtime.
- **Memory Management:** Handles memory allocation and deallocation through a Garbage Collector (GC), freeing developers from manual memory management.
- **Exception Handling:** Provides a structured way to handle runtime errors.
- **Security:** Enforces code access security and type safety.
Base Class Library (BCL)
The BCL is a comprehensive collection of reusable classes, interfaces, and value types that provide foundational functionality. It includes types for:
- File I/O
- Networking
- Collections (lists, dictionaries)
- Text manipulation
- Database connectivity
- And much more.
Cross-Platform Capabilities
With .NET (Core), C# applications can run on Windows, macOS, and Linux. This is a major advantage for modern development, allowing developers to target a wider range of platforms with a single codebase.
Key C# Features
LINQ (Language Integrated Query)
LINQ provides a powerful and consistent way to query data from various sources (objects, databases, XML) directly within C# code, using a SQL-like syntax.
using System.Linq; // Required for LINQ
List names = new List { "Alice", "Bob", "Charlie", "David" };
// Query syntax
var shortNames = from name in names
where name.Length < 6
select name;
// Method syntax
var longNames = names.Where(name => name.Length >= 6).ToList();
Console.WriteLine("Short Names:");
foreach (var name in shortNames)
{
Console.WriteLine(name); // Output: Alice, Bob
}
Console.WriteLine("Long Names:");
foreach (var name in longNames)
{
Console.WriteLine(name); // Output: Charlie, David
}
Asynchronous Programming (async/await)
C# provides the `async` and `await` keywords to simplify asynchronous programming, making it easier to write responsive applications that perform long-running operations without blocking the main thread.
using System.Threading.Tasks; // Required for Task
class AsyncExample
{
public static async Task SimulateLongRunningOperation()
{
Console.WriteLine("Starting long running operation...");
await Task.Delay(3000); // Simulate a 3-second delay
Console.WriteLine("Long running operation finished!");
}
// How to call:
// public static async void Main(string[] args)
// {
// Console.WriteLine("Application started.");
// await SimulateLongRunningOperation(); // Call the async method
// Console.WriteLine("Application finished.");
// Console.ReadKey();
// }
}
Generics
Generics allow you to define classes, methods, and interfaces with placeholders for the type of data they operate on. This provides type safety without sacrificing flexibility.
class MyGenericList // T is a type parameter
{
private List items = new List();
public void Add(T item)
{
items.Add(item);
}
public T Get(int index)
{
return items[index];
}
}
// Usage:
// MyGenericList intList = new MyGenericList();
// intList.Add(10);
// intList.Add(20);
// Console.WriteLine(intList.Get(0)); // Output: 10
// MyGenericList stringList = new MyGenericList();
// stringList.Add("Hello");
// stringList.Add("World");
// Console.WriteLine(stringList.Get(1)); // Output: World
Delegates and Events
**Delegates** are type-safe function pointers that allow you to treat methods as objects. **Events** are a special type of delegate that enable a class or object to notify other classes or objects when something interesting happens.
// 1. Define a delegate type
public delegate void MyDelegate(string message);
class Publisher
{
// 2. Define an event based on the delegate
public event MyDelegate OnMessageSent;
public void SendMessage(string message)
{
Console.WriteLine($"Publisher sending message: {message}");
// 3. Raise the event (invoke the delegate)
OnMessageSent?.Invoke(message); // The '?' checks if there are any subscribers
}
}
class Subscriber
{
public void HandleMessage(string message)
{
Console.WriteLine($"Subscriber received message: {message}");
}
}
// Usage:
// Publisher publisher = new Publisher();
// Subscriber subscriber = new Subscriber();
// // Subscribe the subscriber's method to the publisher's event
// publisher.OnMessageSent += subscriber.HandleMessage;
// publisher.SendMessage("Hello from event!");
// // Output:
// // Publisher sending message: Hello from event!
// // Subscriber received message: Hello from event!
Conclusion and Next Steps
This tutorial has provided a foundational understanding of C# and the .NET platform. C# is a powerful and evolving language with a vast ecosystem. To continue your learning journey, we recommend:
- Practicing coding regularly.
- Building small projects to apply what you've learned.
- Exploring specific areas like ASP.NET Core for web development, Unity for game development, or Xamarin/MAUI for mobile development.
- Consulting the official Microsoft C# documentation and .NET documentation.