Monday, March 2, 2026

Difference Between ref and out keywords in C#

Both ref and out are used to pass arguments by reference in C#.

That means the method can modify the original variable value.


1. ref Keyword

  • Variable must be initialized before passing

  • Used when method reads and modifies the value

  • Memory must already contain a value

Example

void AddTen(ref int number)
{
    number = number + 10;
}

int x = 5;
AddTen(ref x);
// x becomes 15

2. out Keyword

  • Variable does NOT need initialization before passing

  • Method must assign a value before returning

  • Used mainly for returning multiple values

Example

void GetNumber(out int number)
{
    number = 20;
}

int x;
GetNumber(out x);
// x becomes 20

Key Differences (List Format)

  1. Initialization

    • ref → Must initialize before passing

    • out → No need to initialize before passing

  2. Value Assignment Inside Method

    • ref → Optional to assign

    • out → Mandatory to assign

  3. Usage Purpose

    • ref → Modify existing value

    • out → Return value from method

  4. Memory

    • Both pass variable reference (same memory location)


Simple Rule to Remember

  • If variable already has value → use ref

  • If method will create and return value → use out




Behavioral Patterns

 

Behavioral patterns focus on communication between objects and how responsibilities are distributed.

1) Observer Pattern

Notifies multiple objects when one object changes state.

Example

Event notification system.

using System;
using System.Collections.Generic;

public interface IObserver
{
    void Update(string message);
}

public class Subscriber : IObserver
{
    private string _name;

    public Subscriber(string name)
    {
        _name = name;
    }

    public void Update(string message)
    {
        Console.WriteLine(_name + " received: " + message);
    }
}

public class Publisher
{
    private List<IObserver> _observers = new List<IObserver>();

    public void Subscribe(IObserver observer)
    {
        _observers.Add(observer);
    }

    public void Notify(string message)
    {
        foreach (var observer in _observers)
        {
            observer.Update(message);
        }
    }
}

// Usage
Publisher pub = new Publisher();
pub.Subscribe(new Subscriber("User1"));
pub.Notify("New Notification");

2) Strategy Pattern

Defines a family of algorithms and makes them interchangeable.

Example

Different payment methods.

public interface IPaymentStrategy
{
    void Pay(int amount);
}

public class CreditCardPayment : IPaymentStrategy
{
    public void Pay(int amount)
    {
        Console.WriteLine("Paid " + amount + " using Credit Card");
    }
}

public class UpiPayment : IPaymentStrategy
{
    public void Pay(int amount)
    {
        Console.WriteLine("Paid " + amount + " using UPI");
    }
}

public class ShoppingCart
{
    private IPaymentStrategy _paymentStrategy;

    public ShoppingCart(IPaymentStrategy paymentStrategy)
    {
        _paymentStrategy = paymentStrategy;
    }

    public void Checkout(int amount)
    {
        _paymentStrategy.Pay(amount);
    }
}

// Usage
ShoppingCart cart = new ShoppingCart(new UpiPayment());
cart.Checkout(1000);

3) Command Pattern

Encapsulates a request as an object.

Example

public interface ICommand
{
    void Execute();
}

public class Light
{
    public void On()
    {
        Console.WriteLine("Light ON");
    }
}

public class LightOnCommand : ICommand
{
    private Light _light;

    public LightOnCommand(Light light)
    {
        _light = light;
    }

    public void Execute()
    {
        _light.On();
    }
}

// Usage
Light light = new Light();
ICommand command = new LightOnCommand(light);
command.Execute();

4) Chain of Responsibility Pattern

Passes request along a chain of handlers.

Example

public abstract class Handler
{
    protected Handler _next;

    public void SetNext(Handler next)
    {
        _next = next;
    }

    public abstract void HandleRequest(int level);
}

public class LevelOneHandler : Handler
{
    public override void HandleRequest(int level)
    {
        if (level == 1)
            Console.WriteLine("Handled by Level 1");
        else if (_next != null)
            _next.HandleRequest(level);
    }
}

5) Mediator Pattern

Controls communication between objects.

Example

public class ChatRoom
{
    public static void ShowMessage(string user, string message)
    {
        Console.WriteLine(user + ": " + message);
    }
}

6) State Pattern

Changes behavior when internal state changes.

Example

public interface IState
{
    void Handle();
}

public class StartState : IState
{
    public void Handle()
    {
        Console.WriteLine("Machine Started");
    }
}

7) Template Method Pattern

Defines skeleton of algorithm in base class.

Example

public abstract class DataProcessor
{
    public void Process()
    {
        ReadData();
        ProcessData();
        SaveData();
    }

    protected abstract void ReadData();
    protected abstract void ProcessData();

    protected void SaveData()
    {
        Console.WriteLine("Data Saved");
    }
}

8) Iterator Pattern

Provides sequential access without exposing structure.

Example: foreach in C# uses Iterator internally.


9) Memento Pattern

Saves and restores object state.


10) Visitor Pattern

Adds new operations without modifying classes.


11) Interpreter Pattern

Defines grammar and interpreter for language.


Simple Understanding

Observer → Notification system
Strategy → Change algorithm at runtime
Command → Request as object
Chain → Pass request step by step
Mediator → Central communication
State → Behavior changes by state
Template → Fixed algorithm structure
Iterator → Loop through collection
Memento → Undo feature
Visitor → Add new operation
Interpreter → Language parsing

Structural Patterns

 

Structural patterns focus on how classes and objects are composed to form larger structures.

1) Adapter Pattern

Converts one interface into another expected interface.

Example

Old printer class does not match new interface.

// Target interface
public interface IPrinter
{
    void Print();
}

// Existing class (incompatible)
public class OldPrinter
{
    public void PrintOld()
    {
        Console.WriteLine("Printing from Old Printer");
    }
}

// Adapter
public class PrinterAdapter : IPrinter
{
    private OldPrinter _oldPrinter = new OldPrinter();

    public void Print()
    {
        _oldPrinter.PrintOld();
    }
}

// Usage
IPrinter printer = new PrinterAdapter();
printer.Print();

2) Bridge Pattern

Separates abstraction from implementation.

Example

Remote control working with different TVs.

public interface ITV
{
    void On();
}

public class SonyTV : ITV
{
    public void On()
    {
        Console.WriteLine("Sony TV ON");
    }
}

public class SamsungTV : ITV
{
    public void On()
    {
        Console.WriteLine("Samsung TV ON");
    }
}

public class Remote
{
    protected ITV _tv;

    public Remote(ITV tv)
    {
        _tv = tv;
    }

    public void TurnOn()
    {
        _tv.On();
    }
}

// Usage
Remote remote = new Remote(new SonyTV());
remote.TurnOn();

3) Composite Pattern

Treats individual objects and groups of objects uniformly.

Example

File and Folder structure.

public interface IFileSystem
{
    void Show();
}

public class File : IFileSystem
{
    public void Show()
    {
        Console.WriteLine("File");
    }
}

public class Folder : IFileSystem
{
    private List<IFileSystem> _items = new List<IFileSystem>();

    public void Add(IFileSystem item)
    {
        _items.Add(item);
    }

    public void Show()
    {
        Console.WriteLine("Folder:");
        foreach (var item in _items)
        {
            item.Show();
        }
    }
}

// Usage
Folder folder = new Folder();
folder.Add(new File());
folder.Add(new File());
folder.Show();

4) Decorator Pattern

Adds new behavior to an object dynamically.

Example

Adding extra features to coffee.

public interface ICoffee
{
    string GetDescription();
}

public class SimpleCoffee : ICoffee
{
    public string GetDescription()
    {
        return "Plain Coffee";
    }
}

public class MilkDecorator : ICoffee
{
    private ICoffee _coffee;

    public MilkDecorator(ICoffee coffee)
    {
        _coffee = coffee;
    }

    public string GetDescription()
    {
        return _coffee.GetDescription() + " + Milk";
    }
}

// Usage
ICoffee coffee = new MilkDecorator(new SimpleCoffee());
Console.WriteLine(coffee.GetDescription());

5) Facade Pattern

Provides simplified interface to a complex system.

Example

public class CPU
{
    public void Start() => Console.WriteLine("CPU Started");
}

public class Memory
{
    public void Load() => Console.WriteLine("Memory Loaded");
}

public class ComputerFacade
{
    private CPU _cpu = new CPU();
    private Memory _memory = new Memory();

    public void StartComputer()
    {
        _cpu.Start();
        _memory.Load();
        Console.WriteLine("Computer Ready");
    }
}

// Usage
ComputerFacade computer = new ComputerFacade();
computer.StartComputer();

6) Flyweight Pattern

Reduces memory usage by sharing common objects.

Example

public class Circle
{
    public string Color { get; set; }

    public Circle(string color)
    {
        Color = color;
    }

    public void Draw()
    {
        Console.WriteLine("Drawing " + Color + " circle");
    }
}

Instead of creating many same-color objects, reuse existing ones.


7) Proxy Pattern

Controls access to another object.

Example

public interface IImage
{
    void Display();
}

public class RealImage : IImage
{
    public RealImage()
    {
        Console.WriteLine("Loading Image...");
    }

    public void Display()
    {
        Console.WriteLine("Displaying Image");
    }
}

public class ProxyImage : IImage
{
    private RealImage _realImage;

    public void Display()
    {
        if (_realImage == null)
            _realImage = new RealImage();

        _realImage.Display();
    }
}

// Usage
IImage image = new ProxyImage();
image.Display();

Summary (Simple Understanding)

Adapter → Converts interface
Bridge → Separates abstraction & implementation
Composite → Tree structure (part-whole)
Decorator → Adds extra behavior
Facade → Simplifies complex system
Flyweight → Shares objects to save memory
Proxy → Controls access

Creational Design Patterns

Creational patterns deal with object creation mechanisms.


1) Singleton Pattern

Ensures only one instance of a class exists.

Example

Used for logging, configuration, database connection, etc.

public class Logger
{
    private static Logger _instance;

    private Logger() { }

    public static Logger GetInstance()
    {
        if (_instance == null)
            _instance = new Logger();

        return _instance;
    }

    public void Log(string message)
    {
        Console.WriteLine(message);
    }
}

// Usage
Logger log1 = Logger.GetInstance();
Logger log2 = Logger.GetInstance();

Console.WriteLine(log1 == log2); // True (same instance)

2) Factory Method Pattern

Creates object without exposing instantiation logic.

Example

Creating different types of vehicles.

public interface IVehicle
{
    void Drive();
}

public class Car : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Car Driving");
    }
}

public class Bike : IVehicle
{
    public void Drive()
    {
        Console.WriteLine("Bike Riding");
    }
}

public class VehicleFactory
{
    public static IVehicle GetVehicle(string type)
    {
        if (type == "Car")
            return new Car();
        else if (type == "Bike")
            return new Bike();
        else
            return null;
    }
}

// Usage
IVehicle vehicle = VehicleFactory.GetVehicle("Car");
vehicle.Drive();

3) Abstract Factory Pattern

Creates families of related objects.

Example

Creating Windows and Mac UI elements.

public interface IButton
{
    void Render();
}

public class WindowsButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Windows Button");
    }
}

public class MacButton : IButton
{
    public void Render()
    {
        Console.WriteLine("Mac Button");
    }
}

public interface IUIFactory
{
    IButton CreateButton();
}

public class WindowsFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new WindowsButton();
    }
}

public class MacFactory : IUIFactory
{
    public IButton CreateButton()
    {
        return new MacButton();
    }
}

// Usage
IUIFactory factory = new WindowsFactory();
IButton button = factory.CreateButton();
button.Render();

4) Builder Pattern

Builds complex object step by step.

Example

Building a House object.

public class House
{
    public string Walls { get; set; }
    public string Roof { get; set; }
}

public class HouseBuilder
{
    private House _house = new House();

    public HouseBuilder BuildWalls()
    {
        _house.Walls = "Concrete Walls";
        return this;
    }

    public HouseBuilder BuildRoof()
    {
        _house.Roof = "Steel Roof";
        return this;
    }

    public House GetHouse()
    {
        return _house;
    }
}

// Usage
House house = new HouseBuilder()
                .BuildWalls()
                .BuildRoof()
                .GetHouse();

5) Prototype Pattern

Creates new object by copying existing object.

Example

public class Person : ICloneable
{
    public string Name { get; set; }

    public object Clone()
    {
        return this.MemberwiseClone();
    }
}

// Usage
Person p1 = new Person { Name = "Naresh" };
Person p2 = (Person)p1.Clone();

Console.WriteLine(p2.Name);

Summary (Simple Understanding)

Singleton → One object only
Factory → Create object based on condition
Abstract Factory → Create related object families
Builder → Build complex object step by step
Prototype → Copy existing object

What is design pattern?

Design Pattern is a reusable solution to a common problem in software design.
It is not ready-made code, but a template or best practice to solve recurring design problems.
In simple words:
A design pattern tells how to structure classes and objects to solve a problem in a clean and maintainable way.

Types of Design Patterns (GoF – Gang of Four)
Design patterns are mainly divided into 3 categories:

1) Creational Patterns
Used to create objects in a proper and flexible way.
Singleton – Only one instance of a class is created.
Factory Method – Creates objects without specifying exact class.
Abstract Factory – Creates families of related objects.
Builder – Builds complex objects step by step.
Prototype – Creates new objects by copying existing object.

2) Structural Patterns
Used to organize classes and objects into larger structures.
Adapter – Converts one interface into another.
Bridge – Separates abstraction from implementation.
Composite – Treats individual objects and groups uniformly.
Decorator – Adds new behavior to objects dynamically.
Facade – Provides simple interface to complex system.
Flyweight – Reduces memory usage by sharing objects.
Proxy – Controls access to another object.

3) Behavioral Patterns
Used to manage communication between objects.
Observer – Notifies multiple objects when state changes.
Strategy – Defines family of algorithms and makes them interchangeable.
Command – Encapsulates a request as an object.
Chain of Responsibility – Passes request along a chain of handlers.
Mediator – Controls communication between objects.
State – Changes behavior based on internal state.
Template Method – Defines skeleton of algorithm.
Iterator – Access elements sequentially.
Memento – Saves and restores object state.
Visitor – Adds new operation without changing classes.
Interpreter – Defines grammar for a language.


Thursday, February 12, 2026

Static vs Non-Static Class Members in C#

 Static Members :Belong to the class, not to an object.
                            Only one copy exists.
                             Accessed using ClassName.
                            MemberNameMemory allocated only once.
public class Employee
{
    public static string CompanyName = "ABC Ltd";
}
Non-Static Members.
                            Belong to the object (instance).
                            Each object has its own copy.
                            Must create object to access.
public class Employee
{
    public string Name;
}

"Static members belong to the class and are shared by all objects. Non-static members belong to the object and require object creation to access."

Wednesday, February 11, 2026

What is a Class Member in C#

  class members are the variable and functions that are defined inside a class.

  anything written inside a class is called a class members

  types of class members

  Fields
  propertied
  methods
  constructors
  events
  indexers
  and  Nested class

  Ex : public class Employee
  {
  // Field
  private string name;

  // Property
  public string Name { get; set; }

  // Method
  public void Display()
  {
  Console.WriteLine("Employee Name");
  }

  // Constructor
  public Employee()
  {
  Console.WriteLine("Constructor Called");
  }
  }

  "Class members are the variables, properties, methods, and constructors defined inside a class. They represent the data and behavior of the class." 
  

 Fields  - Store data
 Properties - Control data access
 Methods - perform actions

 Constructor  - initialize object

Difference Between var and dynamic in C#

 Var: Var is implicitly typed
         The type is decided at compile time
         Once assigned, the type cannot change
         strongly typed. 
         intellisese worked properly.  
         Errors are checked at compile time

Ex:
var name = "Naresh";   // Compiler treats it as string
// name = 10; ❌ Error (cannot change type)


Dynamic: dynamice is resolved ar runtime
         type checking happens at runtime, not compile time
         the type can change
         no compile time type checking
         intellisense is limited.
         errors may occur at runtime
Ex: 
dynamic value = "Naresh";
value = 10;   // ✅ Allowed

value = true; // ✅ Allowed

Thursday, February 5, 2026

var vs dynamic

1.var
Type is decided at compile time
Strongly typed
Must be initialized at declaration
IntelliSense & compile-time checking available
Example
var x = 10; // int
var name = "Ram"; // string
👉 If you assign a wrong type later → compile-time error

2.dynamic
Type is decided at runtime
Not strongly typed
No compile-time checking
Errors occur at runtime
Example
dynamic x = 10;
x = "Ram"; // allowed
x.DoSomething(); // runtime error if method not found

3.Key Differences (Interview Points)

Feature

var

dynamic

Type resolution

Compile time

Runtime

Type safety

Yes

No

IntelliSense

Yes

No

Error checking

Compile time

Runtime

Type change allowed

No

Yes


4.When to use?
Use var when type is obvious and you want clean code
Use dynamic when working with:
COM objects
Reflection
JSON / loosely typed data

5.Important interview one-liner
var is statically typed, dynamic is dynamically typed.

abstract class

1. What is an Abstract Class?
An abstract class is a partially implemented class.
It can have 
It can have both abstract methods (no body) and normal methods (with body).

2. Key rule
An abstract class cannot be instantiated
It must be inherited by another class

3. What can an abstract class contain?
Abstract methods
Non-abstract (normal) methods
Fields
Properties
Constructors

4. Syntax example (interview-friendly)
abstract class Employee
{
public abstract void Work();

public void Login()
{
// common code
}
}

class Developer : Employee
{
public override void Work()
{
// implementation
}
}

5. Method implementation rule
Abstract methods must be overridden in the derived class
Normal methods are optional to override

6. Inheritance rule
Supports single inheritance only
Multiple inheritance is not allowed with classes

7. Abstract class vs Interface (short point)
Abstract class → Partial abstraction
Interface → Complete abstraction

8. Why do we use abstract classes?
To share common base functionality
To enforce base rules with flexibility
When some behavior is common and some is different

9. Important interview one-liner
An abstract class provides a base class with both implemented and unimplemented methods.