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
Feature | Object-Oriented Programming (OOP) | Object-Based Programming (OBP) |
---|---|---|
Definition | Programming paradigm based on objects that support inheritance, polymorphism, encapsulation, and abstraction. | Programming using objects but without inheritance and polymorphism. |
Key Concepts Supported | Inheritance, polymorphism, encapsulation, abstraction. | Encapsulation and abstraction only. |
Inheritance Support | Supported (classes can inherit from other classes). | Not supported. |
Polymorphism Support | Supported (method overriding, interfaces). | Not supported. |
Encapsulation | Supported (using classes and access modifiers). | Supported. |
Abstraction | Supported (abstract classes, interfaces). | Limited or not supported. |
Examples | C++, Java, C#, Python | JavaScript (early versions), VBScript. |
Use of Classes | Mandatory; objects are instances of classes. | Objects may or may not be instances of classes. |
Method Overloading/Overriding | Supported | Generally 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.
Feature | Explanation |
---|---|
Memory Management | Automatically manages memory using Garbage Collection to allocate and free memory. |
Exception Handling | Provides a structured and consistent way to handle runtime errors (exceptions). |
Security | Enforces Code Access Security (CAS) to restrict what code can do based on permissions. |
Type Safety | Ensures that code only accesses types in safe and intended ways to prevent errors or vulnerabilities. |
Just-In-Time (JIT) Compilation | Converts 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
andMyVar
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.
Type | Description | Example |
---|---|---|
int | Integer (32-bit) | int x = 10; |
float | Floating point (32-bit) | float f = 2.5f; |
double | Double precision float | double d = 3.14; |
char | Single character | char c = 'A'; |
bool | Boolean value | bool flag = true; |
byte | 8-bit unsigned integer | byte b = 255; |
short | 16-bit signed integer | short s = 1000; |
long | 64-bit signed integer | long l = 123456789L; |
decimal | High precision floating point | decimal m = 10.5m; |
Reference Types
Reference types store a reference to the data, not the actual data. They are stored in the heap.
Type | Description | Example |
---|---|---|
string | Sequence of characters | string name = "John"; |
object | Base type for all data types | object obj = 10; |
class | User-defined reference type | class MyClass {} |
interface | Defines a contract | interface IExample {} |
delegate | Represents references to methods | delegate void MyDel(); |
dynamic | Type resolved at runtime | dynamic 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
}