C# Core Concepts: .NET Framework, OOP, and Data Types

Microsoft .NET Framework: Components Explained

The .NET Framework is a Windows-based platform developed by Microsoft used to build and run applications such as web, desktop, and services. It provides a managed environment with features like memory management, security, and cross-language support.

Main Components of .NET Framework

  • Common Language Runtime (CLR): The core execution engine. It manages memory, security, exception handling, and threading. It converts Intermediate Language (IL) to native code via JIT (Just-In-Time) compilation.
  • .NET Framework Class Library (FCL/BCL): A pre-built collection of classes, interfaces, and types. It provides functionality for file I/O, database access, XML, networking, collections, and more.
  • Common Type System (CTS): Defines standard data types used in .NET languages. It ensures interoperability between languages (e.g., C#, VB.NET).
  • Common Language Specification (CLS): A set of rules for language interoperability. It ensures that objects written in different .NET languages can interact.
  • ASP.NET: A framework for building web applications and services. It supports MVC and Web API architectures.
  • Windows Forms & WPF:
    • Windows Forms: For creating traditional desktop applications.
    • WPF (Windows Presentation Foundation): For rich UI applications using XAML.

C# Finalizers and the base Keyword Explained

Understanding Finalizers in C#

A finalizer is used to perform cleanup operations before an object is reclaimed by garbage collection. It is declared using a tilde (~) followed by the class name.

When to Use Finalizers

  • To release unmanaged resources (e.g., file handles, database connections).
  • Automatically called by the Garbage Collector, not manually.

Finalizer Syntax and Example

using System;

class Demo
{
    public Demo()
    {
        Console.WriteLine("Constructor: Object Created");
    }

    ~Demo()
    {
        Console.WriteLine("Finalizer: Object Destroyed");
    }
}

class Program
{
    static void Main()
    {
        Demo obj = new Demo();
        obj = null; // Make object eligible for garbage collection
        GC.Collect(); // Force garbage collection
        GC.WaitForPendingFinalizers(); // Wait for finalizers to complete
        Console.WriteLine("End of Main");
    }
}

Using the base Keyword in C#

Purpose of the base Keyword

  • Call base class constructors.
  • Access base class methods, properties, or fields from the derived class.

base Keyword Example

using System;

class Parent
{
    public Parent()
    {
        Console.WriteLine("Parent constructor called.");
    }

    public void Display()
    {
        Console.WriteLine("Method in Parent class.");
    }
}

class Child : Parent
{
    public Child() : base() // Calls the base class constructor
    {
        Console.WriteLine("Child constructor called.");
    }

    public void Show()
    {
        base.Display(); // Calls the base class method
        Console.WriteLine("Method in Child class.");
    }
}

class Program
{
    static void Main()
    {
        Child obj = new Child();
        obj.Show();
    }
}

C# Dynamic Binding with Virtual Methods

Dynamic binding (also called runtime polymorphism) means that the method to be executed is determined at runtime, not at compile time. A virtual method is a method that can be overridden in a derived class using the override keyword. This allows dynamic method dispatch.

Dynamic Binding Example

using System;

class Animal
{
    public virtual void Speak() // Virtual method
    {
        Console.WriteLine("The animal makes a sound.");
    }
}

class Dog : Animal
{
    public override void Speak() // Overrides the virtual method
    {
        Console.WriteLine("The dog barks.");
    }
}

class Cat : Animal
{
    public override void Speak() // Overrides the virtual method
    {
        Console.WriteLine("The cat meows.");
    }
}

class Program
{
    static void Main()
    {
        Animal a; // Base class reference
        
        a = new Dog(); // Assign a derived class object
        a.Speak();     // Calls Dog's Speak() at runtime

        a = new Cat(); // Assign another derived class object
        a.Speak();     // Calls Cat's Speak() at runtime
    }
}

C# Operator Overloading: Binary Operator Example

Operator Overloading allows you to redefine the behavior of standard operators (+, -, *, etc.) for your user-defined types (like classes or structs). This lets you perform intuitive operations on objects as if they were primitive types.

Binary Operator Overloading Example

using System;

class Complex
{
    public int Real, Imag;

    public Complex(int r, int i)
    {
        Real = r;
        Imag = i;
    }

    // Overload the binary '+' operator
    public static Complex operator +(Complex a, Complex b)
    {
        return new Complex(a.Real + b.Real, a.Imag + b.Imag);
    }

    public void Show()
    {
        Console.WriteLine($"{Real} + {Imag}i");
    }
}

class Program
{
    static void Main()
    {
        Complex c1 = new Complex(1, 2);
        Complex c2 = new Complex(3, 4);
        Complex result = c1 + c2; // Uses the overloaded '+' operator
        result.Show();
    }
}

OOP vs. OBP: Key Differences in Programming

FeatureObject-Oriented Programming (OOP)Object-Based Programming (OBP)
DefinitionProgramming paradigm based on objects that support inheritance, polymorphism, encapsulation, and abstraction.Programming using objects but without inheritance and polymorphism.
Key Concepts SupportedInheritance, polymorphism, encapsulation, abstraction.Encapsulation and abstraction only.
Inheritance SupportSupported (classes can inherit from other classes).Not supported.
Polymorphism SupportSupported (method overriding, interfaces).Not supported.
EncapsulationSupported (using classes and access modifiers).Supported.
AbstractionSupported (abstract classes, interfaces).Limited or not supported.
ExamplesC++, Java, C#, PythonJavaScript (early versions), VBScript.
Use of ClassesMandatory; objects are instances of classes.Objects may or may not be instances of classes.
Method Overloading/OverridingSupportedGenerally not supported.

Common Language Runtime (CLR) and Its Features

CLR (Common Language Runtime) is the core runtime environment of the Microsoft .NET Framework. It manages the execution of .NET programs by providing services like memory management, security enforcement, exception handling, and more. Essentially, it acts as a bridge between the compiled .NET code and the underlying operating system.

FeatureExplanation
Memory ManagementAutomatically manages memory using Garbage Collection to allocate and free memory.
Exception HandlingProvides a structured and consistent way to handle runtime errors (exceptions).
SecurityEnforces Code Access Security (CAS) to restrict what code can do based on permissions.
Type SafetyEnsures that code only accesses types in safe and intended ways to prevent errors or vulnerabilities.
Just-In-Time (JIT) CompilationConverts Intermediate Language (IL) code to native machine code at runtime for execution.

C# Static Classes and Static Constructors

A static class in C# is a class that:

  • Cannot be instantiated (you cannot create objects of it).
  • Can only contain static members (methods, properties, fields).

A constructor is a special method in a class that:

  • Has the same name as the class.
  • Is automatically called when an object is created.

Static Constructor

A static constructor initializes static members of the class. It is called automatically once before the first instance is created or any static members are accessed.

Example: Static Class and Static Constructor

using System;

static class MathHelper // A static class
{
    public static double Pi; // Static field

    static MathHelper() // Static constructor
    {
        Pi = 3.14159;
        Console.WriteLine("Static constructor called to initialize Pi");
    }

    public static double CalculateCircleArea(double radius) // Static method
    {
        return Pi * radius * radius;
    }
}

class Program
{
    static void Main()
    {
        // Accessing a static member automatically calls the static constructor once
        double area = MathHelper.CalculateCircleArea(5);
        Console.WriteLine($"Area of circle: {area}");
    }
}

C# Identifiers, Keywords, and Finding the Greatest Number

Identifiers are names used to identify variables, methods, classes, and other user-defined elements in a program. They must follow these rules:

  • Start with a letter (A-Z or a-z) or an underscore (_).
  • Can be followed by letters, digits (0-9), or underscores.
  • Cannot be the same as any keyword.
  • Are case-sensitive (myVar and MyVar are different).

Keywords are reserved words predefined by C# with special meaning. They cannot be used as identifiers. Examples include: int, class, for, if, else, while, return, etc.

C# Program: Find the Greatest of Three Numbers

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine("Enter three numbers:");
        int num1 = int.Parse(Console.ReadLine());
        int num2 = int.Parse(Console.ReadLine());
        int num3 = int.Parse(Console.ReadLine());

        int greatest;

        if (num1 >= num2 && num1 >= num3)
        {
            greatest = num1;
        }
        else if (num2 >= num1 && num2 >= num3)
        {
            greatest = num2;
        }
        else
        {
            greatest = num3;
        }

        Console.WriteLine($"Greatest number is: {greatest}");
    }
}

C# Value Types vs. Reference Types

Value Types

Value types store actual data directly. Each variable has its own copy of the data. They are usually stored in the stack memory. Common value types include: int, float, bool, char, struct, enum.

Value Type Example

int a = 10;
int b = a; // b gets a copy of a's value
b = 20;    // Changing b does not affect a
Console.WriteLine(a); // Output: 10
Console.WriteLine(b); // Output: 20

Reference Types

Reference types store a reference (address) to the actual data. Variables point to the same object in the heap memory. Common reference types include: class, interface, delegate, object, string (special case).

Reference Type Example

class Person
{
    public string Name;
}

Person p1 = new Person();
p1.Name = "Alice";

Person p2 = p1; // p2 refers to the same object as p1

p2.Name = "Bob"; // Changing p2.Name also changes p1.Name

Console.WriteLine(p1.Name); // Output: Bob
Console.WriteLine(p2.Name); // Output: Bob

C# StringBuilder: Efficient String Manipulation

StringBuilder is a mutable string class in C# used to efficiently create and modify strings. Unlike regular strings (string), which are immutable (cannot be changed once created), StringBuilder allows you to modify the string content without creating new objects each time. This makes it much more efficient when you need to perform multiple string manipulations, such as appending, inserting, or deleting characters.

Example: Using StringBuilder

using System;
using System.Text;

class Program
{
    static void Main()
    {
        StringBuilder sb = new StringBuilder("Hello");
        sb.Append(" World");      // Appends " World"
        sb.Insert(5, ",");        // Inserts "," at index 5
        sb.Replace("World", "C#"); // Replaces "World" with "C#"
        Console.WriteLine(sb.ToString()); // Output: Hello, C#
    }
}

C# Namespaces: Organization and Usage

In C#, a namespace is used to organize code and avoid name conflicts between classes, methods, or other elements in large applications or when using external libraries.

You create a namespace using the namespace keyword, and you can use it with the using directive.

Example: Creating and Using Namespaces

using System;

// Define a namespace
namespace MyApp.MathOperations
{
    public class Calculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }
    }
}

// Use the namespace
using MyApp.MathOperations;

class Program
{
    static void Main()
    {
        Calculator calc = new Calculator();
        int result = calc.Add(10, 20);
        Console.WriteLine("Sum = " + result);
    }
}

.NET Framework: CLR and FCL Explained

The .NET Framework is a software development platform developed by Microsoft. It provides a runtime environment and a rich set of libraries for building and running Windows applications, web applications, and services.

Core Components: CLR and FCL

It is composed of two main components:

  • CLR (Common Language Runtime)
  • FCL (Framework Class Library)

Common Language Runtime (CLR)

The CLR is the core runtime engine of the .NET Framework. It manages the execution of .NET programs and provides key services such as:

  • Memory management (using garbage collection)
  • Exception handling
  • Security
  • Thread management
  • Code verification
  • Just-In-Time (JIT) compilation (converts MSIL to native code at runtime)

Framework Class Library (FCL)

The FCL is a huge collection of reusable classes, interfaces, and value types. It provides support for:

  • File I/O
  • Database access (ADO.NET)
  • Web development (ASP.NET)
  • Windows Forms
  • Networking
  • Collections, LINQ, XML, etc.

C# Method Overloading with Examples

Method Overloading is a feature in C# that allows you to define multiple methods with the same name but different parameters (type, number, or order of parameters) within the same class.

Example of Method Overloading

using System;

class Calculator
{
    // Method to add two integers
    public int Add(int a, int b)
    {
        return a + b;
    }

    // Overloaded method to add two doubles
    public double Add(double a, double b)
    {
        return a + b;
    }
}

class Program
{
    static void Main()
    {
        Calculator calc = new Calculator();
        Console.WriteLine(calc.Add(5, 3));       // Calls int Add(int, int)
        Console.WriteLine(calc.Add(2.5, 3.5));   // Calls double Add(double, double)
    }
}

C# Data Types: Value, Reference, and Pointer

Value Types

Value types store data directly in memory. They are usually stored in the stack.

TypeDescriptionExample
intInteger (32-bit)int x = 10;
floatFloating point (32-bit)float f = 2.5f;
doubleDouble precision floatdouble d = 3.14;
charSingle characterchar c = 'A';
boolBoolean valuebool flag = true;
byte8-bit unsigned integerbyte b = 255;
short16-bit signed integershort s = 1000;
long64-bit signed integerlong l = 123456789L;
decimalHigh precision floating pointdecimal m = 10.5m;

Reference Types

Reference types store a reference to the data, not the actual data. They are stored in the heap.

TypeDescriptionExample
stringSequence of charactersstring name = "John";
objectBase type for all data typesobject obj = 10;
classUser-defined reference typeclass MyClass {}
interfaceDefines a contractinterface IExample {}
delegateRepresents references to methodsdelegate void MyDel();
dynamicType resolved at runtimedynamic x = "hello";

Pointer Types (Unsafe Code)

Pointer types allow direct memory access. They require an unsafe context in C#.

Pointer Type Example

unsafe
{
    int* p; // Declares an integer pointer
    // Further operations with pointers would go here
}