Skip to content
C# Explained — Complete Beginner's Guide

C# Explained — Complete Beginner's Guide

DodaTech Updated Jun 6, 2026 9 min read

C# (pronounced “C sharp”) is a modern, object-oriented programming language developed by Microsoft that runs on the .NET platform, combining the power of C++ with the simplicity of Visual Basic.

What You’ll Learn

You’ll master C# variables, data types, control flow, object-oriented programming (classes, inheritance, interfaces), LINQ for data queries, and async/await for asynchronous operations — all with runnable code and expected output.

Why C# Matters

C# is consistently ranked in the top 5 programming languages worldwide. It’s the primary language for .NET development, used in enterprise applications, games (Unity), cloud services, and desktop tools. At DodaTech, Durga Antivirus Pro uses C# for its Windows scanning engine because of its performance and tight integration with the Windows API.

C# Learning Path

    flowchart LR
  A[.NET Overview] --> B[C# Language]
  B --> C[OOP: Classes & Inheritance]
  C --> D[LINQ & Collections]
  D --> E[ASP.NET Core]
  E --> F[Entity Framework]
  F --> G[Microservices]
  B:::current

  classDef current fill:#f90,color:#fff,stroke:#333,stroke-width:2px
  
Prerequisites: Basic .NET knowledge (see our .NET overview). Familiarity with Python or JavaScript helps. Install .NET SDK and any text editor (VS Code recommended).

C# Basics: Variables and Data Types

Think of variables as labeled boxes. The label is the variable name, and the box’s size determines what you can store in it.

using System;

class Program
{
    static void Main()
    {
        // Integer (whole number) - 32 bits
        int age = 25;
        
        // Double (decimal number) - 64 bits
        double price = 19.99;
        
        // String (text)
        string name = "DodaTech";
        
        // Boolean (true/false)
        bool isActive = true;
        
        // Character (single letter)
        char grade = 'A';
        
        // Decimal (high precision, used for money)
        decimal salary = 50000.00m;
        
        // Display all values
        Console.WriteLine($"Name: {name}");
        Console.WriteLine($"Age: {age}");
        Console.WriteLine($"Price: ${price}");
        Console.WriteLine($"Active: {isActive}");
        Console.WriteLine($"Grade: {grade}");
        Console.WriteLine($"Salary: {salary:C}");
        
        // Type inference with 'var'
        var city = "New York";      // Compiler figures out it's a string
        var temperature = 72.5;     // Compiler figures out it's a double
        Console.WriteLine($"City: {city}, Temp: {temperature}°F");
    }
}

Expected output:

Name: DodaTech
Age: 25
Price: $19.99
Active: True
Grade: A
Salary: $50,000.00
City: New York, Temp: 72.5°F

Key points:

  • C# is statically typed — you declare the type when you create the variable. Once you say int age, it can only hold integers
  • var lets the compiler figure out the type. It still creates a strongly typed variable — var city is still a string, just with less typing
  • {salary:C} formats the decimal as currency (adds $ and commas)
  • The m suffix on 50000.00m tells the compiler this is a decimal, not a double

Control Flow

static void CheckNumber(int number)
{
    if (number > 0)
    {
        Console.WriteLine($"{number} is positive");
    }
    else if (number < 0)
    {
        Console.WriteLine($"{number} is negative");
    }
    else
    {
        Console.WriteLine("Zero");
    }

    // Switch expression (modern C#)
    string category = number switch
    {
        > 0 => "Positive",
        < 0 => "Negative",
        _ => "Zero"     // '_' is the default case
    };
    Console.WriteLine($"Category: {category}");
}

// Usage:
CheckNumber(42);
CheckNumber(-3);
CheckNumber(0);

Expected output:

42 is positive
Category: Positive
-3 is negative
Category: Negative
Zero
Category: Zero

Object-Oriented Programming: Classes

OOP in C# is like creating blueprints. A class is the blueprint. An object is the actual thing built from that blueprint.

// Define a class (blueprint)
public class Employee
{
    // Fields (private data)
    private decimal _salary;
    
    // Properties (controlled access to fields)
    public int Id { get; set; }
    public string Name { get; set; }
    public string Department { get; set; }
    
    // Property with custom logic
    public decimal Salary
    {
        get { return _salary; }
        set
        {
            if (value < 0)
                throw new ArgumentException("Salary cannot be negative");
            _salary = value;
        }
    }
    
    // Read-only property (computed)
    public decimal Bonus => Salary * 0.10m;  // 10% bonus
    
    // Constructor (runs when creating a new employee)
    public Employee(int id, string name, string department, decimal salary)
    {
        Id = id;
        Name = name;
        Department = department;
        Salary = salary;
    }
    
    // Method
    public void DisplayInfo()
    {
        Console.WriteLine($"ID: {Id}, Name: {Name}");
        Console.WriteLine($"Department: {Department}");
        Console.WriteLine($"Salary: {Salary:C}");
        Console.WriteLine($"Bonus: {Bonus:C}");
    }
}

// Usage:
var emp = new Employee(101, "Alice Johnson", "Engineering", 85000);
emp.DisplayInfo();

Expected output:

ID: 101, Name: Alice Johnson
Department: Engineering
Salary: $85,000.00
Bonus: $8,500.00

What’s happening:

  • { get; set; } is an auto-property — C# creates a hidden field and the getter/setter for you
  • The Salary property has custom logic — it won’t accept negative values
  • => Bonus is an expression-bodied member — a shorthand for read-only properties
  • The constructor Employee(...) sets initial values when you create a new Employee()

Inheritance

Inheritance lets you create a specialized version of a class. Think of it like a general “Vehicle” class and a more specific “Car” class.

// Base class
public class Animal
{
    public string Name { get; set; }
    
    public Animal(string name)
    {
        Name = name;
    }
    
    // 'virtual' means this method can be overridden
    public virtual void MakeSound()
    {
        Console.WriteLine("Some generic animal sound");
    }
}

// Derived class
public class Dog : Animal
{
    public string Breed { get; set; }
    
    public Dog(string name, string breed) : base(name)
    {
        Breed = breed;
    }
    
    // 'override' replaces the base class version
    public override void MakeSound()
    {
        Console.WriteLine("Woof! Woof!");
    }
    
    public void Fetch()
    {
        Console.WriteLine($"{Name} is fetching the ball!");
    }
}

// Usage:
var genericAnimal = new Animal("Generic");
genericAnimal.MakeSound();   // "Some generic animal sound"

var myDog = new Dog("Buddy", "Golden Retriever");
myDog.MakeSound();           // "Woof! Woof!"
myDog.Fetch();               // "Buddy is fetching the ball!"
Console.WriteLine($"{myDog.Name} is a {myDog.Breed}");

Expected output:

Some generic animal sound
Woof! Woof!
Buddy is fetching the ball!
Buddy is a Golden Retriever

Key concepts:

  • : Animal means Dog inherits from Animal. Dog gets everything Animal has plus its own additions
  • virtual in the base class says “you may override this”
  • override in the derived class says “I want my own version of this”
  • base(name) calls the parent constructor — you must initialize the base class first

LINQ (Language Integrated Query)

LINQ lets you query collections using SQL-like syntax directly in C#. It’s one of the most powerful features of the language.

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    static void Main()
    {
        var employees = new List<Employee>
        {
            new Employee(1, "Alice", "Engineering", 85000),
            new Employee(2, "Bob", "Marketing", 62000),
            new Employee(3, "Charlie", "Engineering", 92000),
            new Employee(4, "Diana", "Sales", 75000),
            new Employee(5, "Eve", "Engineering", 78000)
        };
        
        // LINQ query syntax (SQL-like)
        var engineers = from e in employees
                        where e.Department == "Engineering"
                        orderby e.Salary descending
                        select e;
        
        Console.WriteLine("Engineers (by salary):");
        foreach (var eng in engineers)
        {
            Console.WriteLine($"  {eng.Name} - {eng.Salary:C}");
        }
        
        // LINQ method syntax (lambda expressions)
        var highEarners = employees
            .Where(e => e.Salary > 70000)
            .OrderBy(e => e.Name)
            .Select(e => $"{e.Name} ({e.Department})");
        
        Console.WriteLine("\nHigh earners (>$70k):");
        foreach (var name in highEarners)
        {
            Console.WriteLine($"  {name}");
        }
        
        // Aggregation
        var avgSalary = employees.Average(e => e.Salary);
        var totalSalary = employees.Sum(e => e.Salary);
        var topSalary = employees.Max(e => e.Salary);
        
        Console.WriteLine($"\nAverage salary: {avgSalary:C}");
        Console.WriteLine($"Total salary: {totalSalary:C}");
        Console.WriteLine($"Top salary: {topSalary:C}");
    }
}

Expected output:

Engineers (by salary):
  Charlie - $92,000.00
  Alice - $85,000.00
  Eve - $78,000.00

High earners (>$70k):
  Alice (Engineering)
  Charlie (Engineering)
  Diana (Sales)
  Eve (Engineering)

Average salary: $78,400.00
Total salary: $392,000.00
Top salary: $92,000.00

Why LINQ matters: Without LINQ, filtering and sorting requires loops and temporary lists. With LINQ, you express what you want, not how to get it. This is called declarative programming.

Security Angle: Input Validation

Like all languages that accept user input, C# apps must validate data:

  • Use decimal.TryParse() instead of decimal.Parse() to handle invalid input without exceptions
  • Sanitize strings with System.Web.HttpUtility.HtmlEncode() before displaying user input in web pages
  • Use SecurityElement.Escape() for XML output
  • Never concatenate user input into SQL queries — use parameterized queries or Entity Framework
  • Store sensitive data in SecureString and clear it immediately after use

The file scanning engine in Durga Antivirus Pro uses C# pattern matching and LINQ extensively to identify malware signatures across millions of files.

Common Mistakes Beginners Make

  1. Confusing == and Equals: For strings, == works in C# (unlike Java). But for custom classes, == checks reference equality unless you override it.
  2. Forgetting break in switch: C# doesn’t need break (it’s non-fall-through), but older switch statements do. Modern switch expressions are cleaner.
  3. Not using StringBuilder for concatenation: string + string creates new objects. For multiple concatenations, use StringBuilder.
  4. Ignoring nullable reference types: Enable nullable in .csproj with <Nullable>enable</Nullable> and handle null properly.
  5. Using ArrayList instead of List<T>: ArrayList (non-generic) requires casting and causes runtime errors. List<T> is type-safe.
  6. Not implementing IDisposable: If your class uses unmanaged resources (file handles, network connections), implement IDisposable.
  7. Overusing var: var is good for obvious types (var x = new List<int>()) but bad when it hurts readability (var result = GetData()).

Practice Questions

  1. What is the difference between int, double, and decimal?
  2. What does the virtual keyword do in a base class method?
  3. What does override do in a derived class?
  4. What does LINQ Where() do?
  5. Why is List<T> better than ArrayList?

Answers:

  1. int = whole numbers (32-bit), double = decimals (64-bit, lower precision), decimal = high-precision decimals for money.
  2. It allows derived classes to override the method with their own implementation.
  3. It replaces the base class method’s implementation with a new one.
  4. It filters a collection based on a condition (predicate).
  5. Type safety (no casting needed), better performance (no boxing), and compile-time error checking.

Challenge

Create a BankAccount class with deposit and withdraw methods. Add a Transaction class that records each transaction with a timestamp. Use LINQ to show all transactions over $100 and calculate the running balance.

Real-World Task

Build a simple employee management system. Create an Employee class, a Department class, and a Company class. Add employees to departments, transfer employees between departments, and generate reports (total salary per department, employee count, etc.) using LINQ.

Featured Snippet

What is C#?

C# is a modern, object-oriented programming language developed by Microsoft that runs on the .NET platform, combining type safety, performance, and productivity features like LINQ and async/await for building enterprise applications.

FAQ

How is C# different from Java?
C# has more features (properties, LINQ, delegates) and is deeply integrated with the .NET ecosystem. Java is more portable but often requires more boilerplate code.
Is C# only for Windows development?
No. With .NET 5+, C# runs on Windows, macOS, and Linux for web, cloud, mobile, and game development.
What can I build with C#?
Web apps (ASP.NET Core), desktop apps (WPF, WinForms), games (Unity), cloud services (Azure), mobile apps (Xamarin/MAUI), and IoT applications.
How long does it take to learn C#?
With prior programming experience, 2-4 weeks to learn basics, 2-3 months to be productive, and 6+ months to master advanced features like async, LINQ, and reflection.

Try It Yourself

▶ Try It Yourself Edit the code and click Run

What’s Next

What’s Next

Congratulations on completing this Csharp tutorial! Here’s where to go from here:

  • Practice daily — Consistency is more important than long study sessions
  • Build a project — Apply what you learned by building something real
  • Explore related topics — Check out other tutorials in the same category
  • Join the community — Discuss with other learners and share your progress

Remember: every expert was once a beginner. Keep coding!

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro