C# Interview Prep

Introduction

C# (pronounced “C Sharp”) is a modern, object-oriented programming language created by Microsoft.
You can use C# to build:

  • Desktop apps (WinForms, WPF)
  • Web apps (ASP.NET Core)
  • Mobile apps (Xamarin / MAUI)
  • Games (Unity)
  • IoT apps
  • Cloud apps (Azure)

//Structure of a Basic C# Program
using System;
class Program
{
    static void Main()
    {
       Console.WriteLine("Hello C#!");
    }
}

Explanation:

using System; → imports namespaces

class Program → class declaration

static void Main() → starting point of program

Console.WriteLine() → prints text on screen

Variables

A variable is used to store data in a program. Each variable has a data type, a name, and an optional initial value.

Syntax for declaring variables:-


    int age = 25;
    string name = "Vishal";
    double price = 99.50;
    bool isActive = true;
    char grade = 'A';

Types of Variables in C#

C# variables are mainly classified into 3 categories:

1. Local Variables

  • Declared inside a method, constructor, or block.
  • Can only be used within that method/block.
  • Must be initialized before use.

Example:

                        
                        
void Test()
{
int number = 10; // local variable
Console.WriteLine(number);
}

2. Instance Variables (Non-static Fields)

  • Declared inside a class, but outside any method.
  • Every object has its own copy of instance variables.

Example:


    class Person
    {
        public string name; // instance variable
        public int age;     // instance variable
    }

3. Static Variables (Static Fields)

  • Declared with the static keyword.
  • Shared by all objects of the class.
  • Only one copy exists in memory.

Example:

                        
                        
    class Counter
    {
    public static int count = 0; // static variable
    }
                        
                        

4. Constant Variables

  • Declared with const
  • Value cannot be changed after initialization.
  • Must be assigned at declaration.

Example:

                        
                        
const double PI = 3.14;
                        
                        

5. Readonly Variables

  • Declared with readonly
  • Value can be set in declaration or in constructor only.
  • After that, it becomes fixed.

Example:



class Demo
{
public readonly int year;

public Demo()
{
year = 2025;
}
}

6. Parameter Variables

  • Variables declared inside method parameters.

Example:

                        
                        
    void Add(int a, int b) // a and b are parameter variables
    {
    }
                        
                        

7. Array Variables

  • Used to store multiple values of the same type.

Example:

                        
                        
                          int[] marks = { 10, 20, 30 };
                        
                        

8. Dynamic Variables

  • Declared using dynamic keyword.
  • Type is checked at runtime.

Example:

                        
                        
    dynamic data = 10;
    data = "Hello"; // valid
                        
                        

Data Types

C# data types are mainly divided into 3 categories:

  • Value Types
  • Reference Types
  • Pointer
Value Types: Stores data directly into the memory (stack).

A variable of a value type stores the actual data directly into the memory. These are derived from the System.ValueType class and are usually stored on the stack. When you assign a value type to another variable, a copy of the value is made, so changes to one variable do not affect the other.

When to Use Value Types: Choose value types for small, immutable data structures that represent a single value.

Examples of Value Types:
  • int
  • float
  • double
  • decimal
  • char
  • bool

Reference Types: Stores a reference (memory address) to the actual data

Reference data types are types where a variable stores a reference (memory address) to the actual data, rather than storing the data itself.

This means that when you assign one reference variable to another,

both variables point to the same object in memory - changes made through one variable are reflected in the other.

  • Stored on the heap (the reference itself is stored on the stack, but the object is on the heap).
  • Multiple variables can reference the same object.
  • Garbage Collector (GC) automatically frees memory when no references remain.

Common Reference Types in C#

  • string
  • class
  • object
  • interface
  • array
  • delegate

using System;

namespace ProgramDataTypes
{
  class Program
  {
    static void Main(string[] args)
    {
        // value type
        int a = 5;
        int b = a;      //in output value b is 5.
        Console.WriteLine(b);

      // reference type
      var arr1 = new int[]{1,2};
      var arr2 = arr1;
      arr2[0] = 99;     //arr1[0] also changes.

      foreach (var num in arr1)
      {
        Console.WriteLine(num);
      }
       
    }
  }
}

Basics of C#

Basics of C# include Structure of C#, Variables, Data Types and Operators.

Class & Object

Class:
Definition: A class is like a blueprint or template for creating objects.

Purpose: It defines the structure (attributes/fields) and behavior (methods/functions) that the objects created from it will have.

Example: Think of a Car Company.
They create a design (class) → which tells how cars should look and have properties like:

  • Color
  • Model
  • Speed
  • Engine capacity

But this design alone is not a real car. It is just a plan or blueprint.

In programming: A class contains Data (called fields or properties) Actions/behaviors (called methods)
A class does not occupy memory until you create an object.


// Class Example
public class Human
{
    public string Name;
    public int Age;

    public void Speak()
    {
        Console.WriteLine("I can speak!");
    }
}

Object:
Definition: An object is an instance of a class.

Purpose: It represents a real-world entity with actual values for the attributes defined in the class.

An object is a real example created from a class.
From the Car blueprint, you can create many actual cars:

  • Car 1 → Red, 120 km/hr
  • Car 2 → Blue, 100 km/hr
Each created car is an object.
In programming: An object is created using the new keyword and occupies memory.


    Human h1 = new Human();
    h1.Name = "Vishal";
    h1.Age = 25;

    Human h2 = new Human();
    h2.Name = "Rahul";
    h2.Age = 30;

    h1.Speak();
    h2.Speak();

Value Type vs Reference Type

Value types (like int, struct) directly hold the value and are usually stored on the stack; assignment copies the actual value. Reference types (class, arrays) store a reference to the object on the heap; assignment copies the reference so both variables point to the same object.

// value copy
int a = 5;
int b = a; // b is 5, independent

// reference copy
var arr1 = new int[]{1,2};
var arr2 = arr1;
arr2[0] = 99; // arr1[0] also changes

Constructors

Constructors initialize new objects. There are default constructors (no parameters), parameterized ones, and static constructors (run once per type). Use parameterized constructors to ensure required values are provided when creating an object.

public class Car {
  public string Model { get; }
  public Car(string model) => Model = model;
}

var c = new Car("Sedan");

Access Modifiers

C# access modifiers control visibility: public (everyone), private (inside type), protected (derived types), internal (same assembly). You can combine them (protected internal, private protected).

Generic Class

A generic class uses a type parameter to work with different types safely. It avoids casting and increases reusability.

public class Box {
  public T Value { get; set; }
  public Box(T v) => Value = v;
}

var intBox = new Box(10);

Encapsulation

Encapsulation hides internal state and exposes behaviour through methods/properties. It protects data from invalid changes and gives a clear API for consumers.

Inheritance

Inheritance lets a class reuse code from a base class. Use it for an “is-a” relationship (Dog is-an Animal). Avoid deep hierarchies—prefer composition when suitable.

Polymorphism

Polymorphism means many forms: at runtime, a base type reference can run overridden methods of derived types (virtual/override). It's essential for flexible, extensible designs.

public class Animal { public virtual void Speak() => Console.WriteLine("..."); }
public class Dog : Animal { public override void Speak() => Console.WriteLine("Woof"); }

Abstract Class vs Interface

Abstract classes can contain implementation and state; interfaces define contracts (methods/properties) and, in recent C# versions, can have default implementations. Use interfaces for loose coupling and abstractions.

Sealed Class

Sealed prevents other classes from inheriting. Use sealed for security, performance, or when extension is not intended.

Array vs List

Array has fixed length and slightly less overhead. List is resizable and provides convenient methods (Add, Remove). Use List for collections that change size.

Dictionary

Dictionary is a fast key-value lookup. Use when you need to find values quickly by key.

IEnumerable vs IQueryable

IEnumerable runs in-memory and is great for local collections. IQueryable builds expression trees so providers like EF can translate queries into SQL and run them on the server.

LINQ Basics

LINQ provides a readable way to query collections (Select, Where, GroupBy). It improves clarity and reduces boilerplate loops.

var evens = numbers.Where(n => n % 2 == 0).ToList();
var names = people.Select(p => p.Name);

FirstOrDefault vs SingleOrDefault

FirstOrDefault returns the first match or default if none; SingleOrDefault expects exactly one result and throws if there are multiple—use Single when you expect one result.

Delegate

A delegate is a type-safe reference to a method. It's like a function pointer and is useful for callbacks and passing behaviour.

public delegate int Calc(int a, int b);
int Add(int x,int y) => x+y;
Calc c = Add;
Console.WriteLine(c(2,3)); // 5

Events

An event exposes a delegate but prevents external code from raising it. It's the usual pattern for publish/subscribe within types (e.g., button click).

Func / Action / Predicate

Built-in delegates: Func returns a value, Action returns void, Predicate returns bool. They simplify passing small methods or lambdas.

Async & Await

Async/await lets you write non-blocking code that looks synchronous. Use async for I/O-bound work (file, network). Avoid blocking calls like .Result on async tasks.

public async Task<string> FetchAsync(string url) {
  using var client = new HttpClient();
  return await client.GetStringAsync(url);
}

Thread vs Task

A Thread maps to an OS thread. A Task is a higher-level abstraction used with the thread pool and async/await. Prefer Task for async and scalable I/O code.

Garbage Collection

The .NET GC frees unreachable managed objects. It's generational (Gen 0/1/2). For unmanaged resources, implement IDisposable and call Dispose or use using.

Boxing & Unboxing

Boxing wraps a value type into an object (heap allocation). Unboxing extracts it back. Avoid boxing in tight loops because of allocations and performance cost.

IDisposable / using

IDisposable allows deterministic release of resources. Prefer using statements to ensure Dispose is called even if exceptions occur.

using (var s = File.OpenRead("file.txt")) {
  // use stream
}

Reflection

Reflection inspects types at runtime (properties, methods). Useful for DI, serializers, or tools, but slower and bypasses compile-time checks—use carefully.

Singleton & DI (short)

Singleton provides one instance but is hard to test. Dependency Injection (DI) is preferred for decoupling; it makes testing and swapping implementations easy.