C# Introduction

C# is a modern, general-purpose programming language used to build web apps, desktop software, games, cloud services, mobile apps, and command-line tools. It matters because it combines readable syntax with strong type checking, excellent tooling, and the power of the .NET platform. In this introduction, you will learn what C# is, what happens when a program runs, and how to read and write your first small programs with confidence.

Overview: What C# Is and How It Works

C# is a strongly typed, object-oriented language created by Microsoft and developed in the open as part of the .NET ecosystem. Strongly typed means each value has a known type, such as int, string, or bool, and the compiler checks that you use those values correctly. Object-oriented means programs are commonly organized into classes, objects, methods, and data, although modern C# also supports functional patterns, records, pattern matching, asynchronous programming, and concise syntax.

A C# program usually runs on .NET. .NET includes the Base Class Library, which provides ready-made types such as Console, List<T>, DateTime, and HttpClient, and the Common Language Runtime, often called the CLR. The CLR is responsible for loading your program, managing memory, running garbage collection, handling exceptions, enforcing type safety, and compiling intermediate code into machine code while the program executes.

The build process has two important stages. First, the C# compiler checks your source code and converts it into Intermediate Language, also called IL, stored in an assembly such as a .dll or .exe. Second, when the program runs, the Just-In-Time compiler turns the IL for the methods being used into native instructions for the current operating system and processor. This is why the same C# source can be built for Windows, Linux, and macOS while still getting efficient native execution.

C# is commonly used with Visual Studio, Visual Studio Code, Rider, and the dotnet command-line tools. A typical project contains a .csproj file that describes the target framework and settings, plus one or more .cs files containing source code. In this course, examples use an explicit Program class and Main method so the entry point is visible from the beginning.

Syntax

A minimal C# console program has a namespace import, a class, an entry-point method, and statements inside that method:

using System;

class Program
{
    static void Main()
    {
        string language = "C#";
        int version = 12;

        Console.WriteLine($"Welcome to {language}");
        Console.WriteLine(version + 5);
    }
}

Output:

Welcome to C#
17
Part Meaning
using System; Makes types in the System namespace, such as Console, available without writing the full name.
class Program Declares a class named Program. A class is a container for methods and data.
static void Main() Defines the entry point. static means it runs without creating an object, and void means it returns no value.
{ } Braces group code into a block. Classes, methods, loops, and conditionals use blocks.
; Ends most statements. Forgetting it is one of the first compile errors beginners meet.
$"...{value}..." Creates an interpolated string, inserting values directly into text.

Examples

Example 1: Printing Text and Numbers

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("C# runs on .NET.");
        Console.WriteLine("It checks types before the program runs.");
        Console.WriteLine(10 + 15);
    }
}

Output:

C# runs on .NET.
It checks types before the program runs.
25

This program calls Console.WriteLine three times. The first two calls print strings, while the third prints the result of an integer expression. C# evaluates 10 + 15 before passing the result to WriteLine, so the output is 25, not the literal expression.

Example 2: Variables, Types, and Decisions

using System;

class Program
{
    static void Main()
    {
        string name = "Maya";
        int completedLessons = 4;
        int requiredLessons = 6;
        bool canTakeQuiz = completedLessons >= requiredLessons;

        Console.WriteLine($"Student: {name}");
        Console.WriteLine($"Lessons completed: {completedLessons}");

        if (canTakeQuiz)
        {
            Console.WriteLine("Quiz unlocked");
        }
        else
        {
            Console.WriteLine("Keep going");
        }
    }
}

Output:

Student: Maya
Lessons completed: 4
Keep going

Here, name stores text, completedLessons and requiredLessons store whole numbers, and canTakeQuiz stores a true-or-false result. The comparison completedLessons >= requiredLessons is evaluated before the if statement runs. Because 4 is not greater than or equal to 6, the else block executes.

Example 3: A Small Method

using System;
using System.Globalization;

class Program
{
    static void Main()
    {
        CultureInfo culture = CultureInfo.GetCultureInfo("en-US");
        decimal subtotal = 39.95m;
        decimal taxRate = 0.0825m;
        decimal total = CalculateTotal(subtotal, taxRate);

        Console.WriteLine($"Subtotal: {subtotal.ToString("C", culture)}");
        Console.WriteLine($"Total: {total.ToString("C", culture)}");
    }

    static decimal CalculateTotal(decimal subtotal, decimal taxRate)
    {
        return subtotal + (subtotal * taxRate);
    }
}

Output:

Subtotal: $39.95
Total: $43.25

This example introduces a method named CalculateTotal. The method accepts two decimal values and returns another decimal. The m suffix tells C# that the numeric literals are decimals, which are preferred for money because they avoid many binary floating-point rounding surprises. The C format prints the values as currency, and the explicit en-US culture keeps the shown output the same on every machine.

How C# Works Step by Step

  1. You write source code in one or more .cs files. The code is plain text, but it must follow C# grammar exactly.
  2. The compiler parses the code, checks names, checks types, and reports errors such as missing semicolons or assigning a string to an int.
  3. If compilation succeeds, the compiler emits an assembly containing IL and metadata. Metadata describes the types, methods, parameters, and references in the program.
  4. When you run the program, the CLR loads the assembly and locates the entry point, here Program.Main.
  5. As methods are needed, the JIT compiler converts their IL into native machine instructions. The program then executes those instructions.
  6. During execution, the CLR tracks object references and automatically frees unreachable managed objects through garbage collection. Value types such as many local int and decimal values can often be stored directly in stack frames or optimized by the JIT, while objects are usually allocated on the managed heap.

This pipeline gives C# a useful balance: early compiler errors catch many bugs before runtime, while the runtime provides portability, memory management, and optimized execution.

Common Mistakes

Missing the Entry Point

The following code defines a class but does not define the Main method that a console program needs as its starting point:

using System;

class Program
{
    static void Start()
    {
        Console.WriteLine("Hello");
    }
}

Correct it by naming the entry method Main:

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Hello");
    }
}

Output:

Hello

Confusing Assignment with Comparison

A single equals sign assigns a value. It does not compare two values, so this condition is invalid:

using System;

class Program
{
    static void Main()
    {
        int score = 100;

        if (score = 100)
        {
            Console.WriteLine("Perfect");
        }
    }
}

Use == when you want to compare:

using System;

class Program
{
    static void Main()
    {
        int score = 100;

        if (score == 100)
        {
            Console.WriteLine("Perfect");
        }
    }
}

Output:

Perfect

Choosing the Wrong Numeric Type

For money, avoid casual use of double unless you understand binary floating-point behavior. decimal is usually a better default for financial values:

using System;

class Program
{
    static void Main()
    {
        decimal price = 19.99m;
        decimal tax = 1.65m;
        Console.WriteLine(price + tax);
    }
}

Output:

21.64

Best Practices

  • Prefer clear names such as completedLessons over vague names such as x.
  • Let the compiler help you. Treat warnings seriously and fix type mismatches instead of working around them.
  • Use decimal for money, int for normal whole-number counts, bool for true-or-false state, and string for text.
  • Keep Main small as programs grow. Move repeated or meaningful work into methods with clear names.
  • Format code consistently. Indentation does not change meaning in C#, but it makes block structure readable.
  • Read error messages from the top first. Later errors are often side effects of the first real mistake.
  • Use interpolated strings for readable output when combining text and values.

Practice Exercises

  1. Write a program that stores your name, favorite programming language, and current lesson number in variables, then prints one sentence using string interpolation.
  2. Create two int variables named minutesStudied and dailyGoal. Print Goal met if the first is greater than or equal to the second; otherwise print Keep studying.
  3. Write a method named AddTax that accepts a decimal price and a decimal tax rate, then returns the final price.

Summary

  • C# is a strongly typed language that commonly runs on the .NET platform.
  • The compiler checks your source code and produces IL; the CLR loads that IL and the JIT turns it into native instructions.
  • A console program starts in static void Main() inside a class.
  • Variables have types, and those types control what values and operations are allowed.
  • Small methods make programs easier to read, test, and reuse.
  • Beginner mistakes such as missing Main, using = instead of ==, or picking the wrong numeric type are easy to avoid once you know what the compiler expects.