C# Notes
C# Notes
NET Framework
Here, I am going to give you an overview of the DOT NET Framework. This is important for
you as a dot net developer to know the history and evolu on of the DOT NET Framework.
Here, in this session, first, we will discuss what was there before the .NET Framework and
what problems we face in that, and how we overcome all those problems in the .NET
Framework. Before DOT NET Framework COM is there. So, let us first discuss what is COM
and what problems we face in COM.
What is COM?
COM stands for Component Object Model. The COM is one of the Microso Frameworks.
Using this Framework, we can develop Windows Applica ons (Desktop or Standalone
Applica ons for Windows OS) as well as Web Applica ons. In earlier COM, VB is the
programming language that is used to implement Windows applica ons and ASP is the
technology used to implement web applica ons.
What are the disadvantages of COM?
There are two major disadvantages of the COM Framework. They are as follows:
1. Incomplete Object-Oriented Programming means it will not support all the features
of OOPs.
2. Pla orm Dependent means COM applica ons can run on only Windows OS.
// Methods
public void Display()
{
Console.WriteLine($"Id: {Id}, Name: {Name}");
}
}
Object Crea on:
C#
MyClass obj1 = new MyClass();
obj1.Id = 1;
obj1.Name = "John Doe";
obj1.Display();
// Part 2
public par al class MyClass
{
// ...
}
Sta c Class:
o Contains only sta c members (methods and fields).
o Cannot be instan ated.
o Used for u lity methods and constants.
o Example:
C#
public sta c class MathU ls
{
public sta c double PI = 3.14159;
public sta c int Add(int a, int b)
{
return a + b;
}
}
7. Key Points
Classes and objects are fundamental concepts in object-oriented programming.
Understanding the rela onship between classes and objects is essen al for effec ve C#
programming.
Different types of classes offer varying levels of flexibility and control.
Constructors in C#
1. Introduc on
A constructor is a special method within a class that is automa cally called when an object of
that class is created.
Its primary purpose is to ini alize the object's state (proper es/fields).
2. Key Characteris cs
Name: The constructor's name must be the same as the class name.
Return Type: Constructors do not have a return type, not even void.
Purpose:
o Ini alize the object's proper es.
o Allocate necessary resources.
Types:
o Default Constructor (Parameterless):
A constructor that takes no arguments.
The compiler provides a default constructor if no other constructors are
defined in the class.
o Parameterized Constructor:
A constructor that accepts arguments.
Allows for flexible object ini aliza on with different values.
3. Implicit Constructor
The compiler automa cally generates a default constructor (parameterless) if no other
constructors are defined explicitly in the class.
This implicit constructor ini alizes the fields of the class with their default values (e.g., 0 for
integers, null for strings).
4. Explicit Constructor
A constructor that is defined explicitly by the programmer.
Can be parameterless or parameterized.
Allows for custom ini aliza on logic.
5. Example: Implicit Constructor
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
public Employee()
{
Console.WriteLine("Default Constructor Called");
}
}
7. Example: Explicit Parameterized Constructor
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
Constructors in C#
1. Introduction
A constructor is a special method within a class that is automatically called whenever
an object of that class is created.
Its primary purpose is to initialize the object's state (properties/fields) with appropriate
values.
2. Key Characteristics
Name: The constructor's name must be the same as the class name.
Return Type: Constructors do not have a return type, not even void.
Purpose:
o Initialize the object's properties.
o Allocate necessary resources.
o Perform custom logic at object creation.
Types:
o Default Constructor (Parameterless):
A constructor that takes no arguments.
The compiler provides a default constructor if no other constructors are
defined in the class. It initializes fields with their default values (e.g., 0
for integers, null for strings).
o Parameterized Constructor:
A constructor that accepts arguments.
Allows for flexible object initialization with different values.
3. Implicit Constructor
The compiler automatically generates a default constructor (parameterless) if no other
constructors are defined explicitly in the class.
4. Explicit Constructor
A constructor that is defined explicitly by the programmer.
Can be parameterless or parameterized.
Allows for custom initialization logic.
5. Example: Implicit Constructor
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
}
// The compiler generates an implicit default constructor:
// public Employee()
// {
// Id = 0;
// Name = null;
// }
6. Example: Explicit Parameterless Constructor
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Employee()
{
Console.WriteLine("Default Constructor Called");
}
}
7. Example: Explicit Parameterized Constructor
C#
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
Console.ReadLine();
}
}
Export to Sheets
3. Examples
Static Constructor:
C#
public class MyClass
{
public static int StaticCount;
static MyClass()
{
Console.WriteLine("Static Constructor Called");
StaticCount = 0;
}
public MyClass()
{
Console.WriteLine("Non-Static Constructor Called");
InstanceCount = 1;
}
// Creating an object will trigger the static constructor (if not already triggered)
// and then the instance constructor
MyClass obj1 = new MyClass();
static MyClass()
{
Console.WriteLine("Static Constructor Called");
StaticCount = 0;
}
public MyClass()
{
Console.WriteLine("Non-Static Constructor Called");
InstanceCount = 1;
}
}
7. Diagram
Openindownaveen-metta.medium.com
class diagram illustrating the execution order of static and nonstatic constructors
8. Conclusion
Static and non-static constructors play crucial roles in object initialization in C#.
Understanding their differences and how they are executed is essential for writing
efficient and well-structured C# code.
By effectively using static and non-static constructors, you can manage the
initialization of class members and control the execution flow within your classes.
Private Constructors in C#
1. Introduction
A private constructor is a constructor declared with the private access modifier.
It restricts object creation from outside the class.
2. Key Characteristics
Access: Can only be accessed within the class itself.
Object Creation:
o Cannot be used to create objects directly from outside the class.
o Can be used to create objects within the same class.
Inheritance:
o If a class has only a private constructor, it cannot be inherited by other classes
(except nested classes within the same class).
3. Examples
Private Constructor Only:
C#
public class MyClass
{
private MyClass()
{
Console.WriteLine("Private Constructor Called");
}
private Singleton()
{
// ...
}
Destructors in C#
1. Introduction
A destructor is a special method in C# that is automatically called by the garbage
collector when an object is no longer in use.
Its primary purpose is to perform any necessary cleanup operations before the object's
memory is reclaimed.
2. Key Characteristics
Name: The destructor's name is the same as the class name preceded by a tilde (~).
Access Modifier: Destructors cannot have any access modifiers (public, private,
protected).
Parameters: Destructors cannot have any parameters.
Return Type: Destructors do not have a return type.
Execution:
o Called implicitly by the garbage collector when the object is eligible for
garbage collection.
o The exact timing of destructor execution is not deterministic.
3. When is an Object Eligible for Garbage Collection?
When all references to the object have been lost.
When the application terminates.
4. Example
C#
public class MyClass
{
public MyClass()
{
Console.WriteLine("Constructor Called");
}
~MyClass()
{
Console.WriteLine("Destructor Called");
}
}
5. Calling the Garbage Collector
You can request the garbage collector to run by calling GC.Collect().
However, relying heavily on GC.Collect() can negatively impact performance.
6. Destructor Implementation
Destructors are implemented using the Finalize method in the .NET runtime.
The Finalize method is called recursively for all objects in the inheritance chain.
7. Important Points
Destructors cannot be called explicitly.
Destructors should be used sparingly and only when necessary to release unmanaged
resources (e.g., file handles, database connections).
Relying heavily on destructors can negatively impact performance.
8. Dispose Pattern
The preferred way to release unmanaged resources is by implementing the
IDisposable interface and providing a Dispose() method.
The Dispose() method allows for explicit resource cleanup and provides more control
over the timing of resource release.
The Dispose() method should be called by the user of the object when they are
finished with it.
9. Code Example (Dispose Pattern)
C#
public class MyClass : IDisposable
{
private bool disposedValue = false; // To detect redundant calls
~MyClass()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
~MyClass()
{
Dispose(false);
}
}
By following these practices, you can ensure efficient memory management and
prevent memory leaks in your .NET applications.
Additional Notes
The GC is a complex system with various configurations and settings you can explore
for advanced memory management scenarios.
Tools like the .NET Memory Profiler can help you analyze memory usage and
identify potential issues.
disposedValue = true;
}
}
~ResourceHolder()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
Abstrac on in C#
Abstrac on is a fundamental concept in object-oriented programming (OOP) that focuses on
exposing essen al func onali es (what an object does) while hiding implementa on details (how it
does it). It simplifies complex systems by breaking them down into smaller, more manageable units.
This promotes code reusability, maintainability, and flexibility.
Key Concepts
Focus on Behavior: Define the services (methods) an object provides without revealing the
underlying logic. Users interact with these services without needing to know the intricate
workings of the object.
Data Hiding: Encapsulate data (member variables) within a class and control access through
methods (ge ers and se ers) or proper es. This safeguards data integrity and prevents
unauthorized modifica ons.
Interfaces: Define contracts outlining the services an object must implement. Classes can
inherit from interfaces and provide concrete implementa ons for the specified methods.
This promotes loose coupling and allows for interchangeable implementa ons.
Abstract Classes: Serve as blueprints for derived classes by defining a set of abstract
methods (without implementa on) and poten ally concrete methods. Derived classes
inherit and provide implementa ons for abstract methods, achieving par al or complete
abstrac on.
Benefits of Abstrac on
Simplified Code: Users focus on how to u lize an object's services without ge ng bogged
down in implementa on details.
Increased Maintainability: Changes to internal workings don't necessarily affect how users
interact with the object, making modifica ons easier and less error-prone.
Enhanced Reusability: Well-abstracted components can be reused in different contexts
without modifica on, promo ng code efficiency.
Improved Security: Sensi ve data can be protected by restric ng access through methods
and proper es, preven ng unauthorized modifica ons.
Flexibility in Design: Abstract classes and interfaces facilitate the crea on of interchangeable
implementa ons, fostering a more flexible and adaptable codebase.
Implementa on Examples
1. Abstrac on Using Interfaces
C#
public interface IShape
{
double CalculateArea();
}
// Usage
IShape circle = new Circle { Radius = 5 };
IShape square = new Square { SideLength = 3 };
// Usage
Shape circle = new Circle { Radius = 5 };
Shape square = new Square { SideLength = 3 };
class Program
{
sta c void Main(string[] args)
{
Dog myDog = new Dog();
myDog.MakeSound(); // Inherited from Animal
myDog.Bark(); // Defined in Dog
}
}
Benefits of Inheritance
Code Reusability: Avoids code duplica on by inheri ng common proper es and behaviors
from a parent class.
Improved Code Organiza on: Creates a hierarchical structure that reflects real-world
rela onships.
Enhanced Maintainability: Changes made to the parent class are automa cally reflected in
all derived classes.
Extensibility: Allows for the crea on of specialized classes by adding new features or
modifying exis ng behavior.
Key Points
Inheritance is a powerful tool for crea ng flexible and reusable code.
Understanding the rules of inheritance is crucial for effec ve object-oriented design.
U lize inheritance judiciously to maintain a well-structured and maintainable codebase.
Types of Inheritance in C#
In C#, inheritance can be broadly classified into two main types:
1. Implementa on Inheritance
Defini on: This type of inheritance occurs when a class derives from another class.
Characteris cs:
o The derived class inherits both data members (fields) and member func ons
(methods) from the base class.
o It allows for code reuse and promotes a hierarchical rela onship between classes.
o Subtypes:
Single Inheritance: A class inherits from only one immediate base class.
(e.g., class DerivedClass : BaseClass { ... })
Mul -level Inheritance: A chain of inheritance where a class inherits from
another derived class. (e.g., class A { ... }, class B : A { ... }, class C : B { ... })
Hierarchical Inheritance: Mul ple classes inherit from a single base class.
(e.g., class A { ... }, class B : A { ... }, class C : A { ... })
2. Interface Inheritance
Defini on: This type of inheritance occurs when a class implements an interface.
Characteris cs:
o A class that implements an interface must provide concrete implementa ons for all
the methods declared in the interface.
o Interfaces define a contract that classes must adhere to.
o Allows for polymorphism and loose coupling between classes.
Key Points:
Mul ple Inheritance (with Classes): C# does not directly support mul ple inheritance with
classes. This means a class cannot inherit from mul ple base classes directly.
Hybrid Inheritance: A combina on of various inheritance types (single, mul -level,
hierarchical) can be considered hybrid inheritance. However, it's not a dis nct category in C#.
Example: Implementa on Inheritance
C#
public class Animal
{
public void MakeSound()
{
Console.WriteLine("Generic animal sound");
}
}
class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
}
Here, Employee HAS-A Address through the member variable Address.
Key Differences
Feature IS-A (Inheritance) HAS-A (Composi on)
Nature Inheritance (parent-child) Composi onal
Coupling Stronger Looser
Usage Extension, specializa on Requires func onality/proper es
Flexibility Limited ( ghtly bound) More flexible (easily modified)
Export to Sheets
Choosing the Right Rela onship
The choice between IS-A and HAS-A depends on the nature of the rela onship between your classes.
Ask yourself:
Is the derived class a specialized version of the base class? (IS-A)
Does the container class need func onali es provided by another class's object? (HAS-A)
Here's a quick guideline:
If the statement "DerivedClass IS-A BaseClass" makes sense, use inheritance.
If the statement "ContainerClass HAS-A AnotherClass" makes sense, use composi on.
Remember
Inheritance is implemented using the : syntax (e.g., class DerivedClass : BaseClass { ... }).
Composi on is simply declaring a variable of another class inside a class.
Generaliza on and Specializa on in C#
Generaliza on
Concept:
o Iden fying commonali es among a group of exis ng classes and crea ng a new,
more general (parent) class.
o This parent class encapsulates the shared features of the child classes.
Example:
o Consider classes like Circle, Square, and Rectangle. They all share the concept of
being "shapes."
o We can create a generalized class called Shape that includes common proper es like
Area and Perimeter.
o Circle, Square, and Rectangle would then inherit from the Shape class, inheri ng the
common proper es and implemen ng their specific area and perimeter calcula ons.
Specializa on
Concept:
o Crea ng new, more specialized classes (child classes) from an exis ng base class.
o These derived classes inherit the proper es and behaviors of the base class and add
their own unique characteris cs.
Example:
o You have a base class Animal with general characteris cs like Eat() and Sleep().
o You can create specialized classes like Dog, Cat, and Bird that inherit from Animal
and add specific behaviors like Bark(), Meow(), and Fly().
Key Differences
Feature Generaliza on Specializa on
Direc on Bo om-up (from specific to general) Top-down (from general to specific)
Purpose Iden fy commonali es, create a superclass Create specialized versions of a base class
Base Class Created a er child classes exist Already exists
Export to Sheets
In C#
Generaliza on: O en achieved using interfaces or abstract classes.
Specializa on: Achieved through class inheritance.
Example (Generaliza on)
C#
interface IShape
{
double CalculateArea();
}
Console.WriteLine("\nCurrent Account:");
IBankAccount currentAccount = new CurrentAccount();
currentAccount.DepositAmount(500);
currentAccount.DepositAmount(1500);
currentAccount.WithdrawAmount(2600);
currentAccount.WithdrawAmount(1000);
Console.WriteLine($"Current Account Balance: {currentAccount.CheckBalance()}");
Console.ReadLine();
}
}
Key Benefits
Polymorphism: The IBankAccount interface allows you to treat both SavingAccount and
CurrentAccount objects uniformly.
Extensibility: You can easily add new account types (e.g., "Fixed Deposit") by crea ng new
classes that implement the IBankAccount interface.
Maintainability: Changes to the interface will automa cally affect all implemen ng classes,
ensuring consistency across the system.
Mul ple Inheritance in C#
C# does not directly support mul ple inheritance for classes. This means a class can only inherit
from one parent class at a me. However, interfaces provide a way to achieve similar func onality.
Why not Mul ple Inheritance with Classes?
The primary reason for not allowing mul ple inheritance with classes is the ambiguity problem.
Imagine a scenario where two parent classes have methods with the same name and signature.
When inheri ng from both classes, the compiler wouldn't know which method implementa on to
use, leading to errors.
Interfaces to the Rescue
Interfaces define contracts that classes can implement. A class can implement mul ple interfaces,
inheri ng their methods and proper es without the ambiguity problem. Here's how it works:
Interfaces only contain method declara ons, not implementa ons.
Classes implemen ng an interface must provide implementa ons for all declared methods.
Benefits of Using Interfaces for Mul ple Inheritance
Flexibility: Classes can inherit behavior from mul ple interfaces without conflicts.
Extensibility: New interfaces can be created without modifying exis ng classes.
Loose Coupling: Interfaces promote loose coupling between classes, making code more
maintainable and testable.
Example: Bank Account System
Let's consider a bank account system with different account types (Savings and Current). Here's how
we can use interfaces for mul ple inheritance:
1. Define an IBankAccount interface with common func onali es like Deposit, Withdraw, and
CheckBalance.
2. Create separate SavingsAccount and CurrentAccount classes implemen ng IBankAccount.
3. Each class provides specific implementa ons for deposit/withdrawal rules based on their
account type.
Code Example
C#
interface IBankAccount
{
bool Deposit(decimal amount);
bool Withdraw(decimal amount);
decimal CheckBalance();
}
1. github.com
github.com
Types of Polymorphism in C#
There are two main types of polymorphism in C#:
1. Compile-Time Polymorphism (Sta c Polymorphism, Early Binding):
o The behavior of a method is determined at compile me based on the method
signature (name and number and types of parameters).
o Achieved through method overloading.
o Method overloading allows mul ple methods with the same name but different
signatures within the same class.
o The compiler selects the appropriate method based on the arguments used in the
call.
2. Run-Time Polymorphism (Dynamic Polymorphism, Late Binding):
o The behavior of a method is determined at run me based on the object's actual
type.
o Achieved through inheritance and method overriding.
o A subclass (derived class) can override a method inherited from its parent (base
class) to provide its own implementa on.
o When a method is called on a reference variable of the parent class type, the actual
object's type determines which method implementa on is executed at run me.
Benefits of Polymorphism
Flexibility: Code can adapt to different situa ons based on the object type.
Reusability: Methods can be wri en in a generic way to handle different types of objects.
Maintainability: Code is easier to understand and modify because the logic is centralized in
methods.
Example: Shape Inheritance
C#
class Shape
{
public virtual void Draw() // Virtual method for overriding
{
Console.WriteLine("Drawing a shape");
}
}
class Program
{
sta c void Main(string[] args)
{
Shape[] shapes = { new Circle(), new Square() };
foreach (Shape shape in shapes)
{
shape.Draw(); // Calls the appropriate Draw method based on object type at run me
}
}
}
Output:
Drawing a circle
Drawing a square
Key Points
Polymorphism is a powerful tool for wri ng flexible and reusable code.
Compile- me polymorphism uses method signatures for binding, while run- me
polymorphism uses object types for binding.
Inheritance and method overriding are essen al for achieving run- me polymorphism.
Consider using interfaces for alterna ve inheritance-like behavior without the ambiguity
problem of mul ple class inheritance.
Method Overloading in C#
Method overloading is a fundamental concept in object-oriented programming (OOP) that allows you
to define mul ple methods with the same name within a class, but with different signatures. The
signature of a method is determined by the number, type, and order of its parameters.
Key Points:
Allows for cleaner and more intui ve code.
Improves code readability and maintainability.
Enables polymorphism (one method name, different behaviors based on arguments).
Achieved through differences in method signatures, not return types.
Benefits of Method Overloading:
Flexibility: Code can adapt to different situa ons based on the arguments provided.
Reusability: Methods can be wri en in a generic way to handle various data types.
Readability: Code becomes more readable as overloaded methods o en have clear names
reflec ng their purpose.
Example:
C#
class Shape
{
public virtual void Draw() // Virtual method for overriding
{
Console.WriteLine("Drawing a shape");
}
}
class Program
{
sta c void Main(string[] args)
{
Shape[] shapes = { new Circle(), new Square() };
foreach (Shape shape in shapes)
{
shape.Draw(); // Calls the appropriate Draw method based on object type at run me
(polymorphism)
}
}
}
Output:
Drawing a circle
Drawing a square
When to Use Method Overloading:
When you need to perform the same opera on on different data types.
When you want to provide mul ple ways to call a method with varying amounts of data.
To improve code readability by using descrip ve method names with overloaded versions for
different scenarios.
Things Not Considered in Method Signature:
Return Type: While methods can have different return types, it's not part of the signature for
overloading. You cannot overload methods based solely on return type differences.
Access Specifiers (public, private, protected): These can be different for overloaded
methods.
Access Modifiers (sealed, sta c, virtual): These can also be different for overloaded
methods.
Overloading vs. Overriding:
Overloading: Occurs within the same class, methods have the same name but different
signatures.
Overriding: Occurs in inheritance hierarchies, a subclass redefines a method inherited from
its parent class.
Addi onal Notes:
Method overloading is resolved at compile me.
C# allows overloading constructors (special methods for object crea on) based on parameter
differences.
Method Overriding in C#
Method overriding is a fundamental object-oriented programming (OOP) concept that allows you to
redefine the behavior of an inherited method in a subclass. It enables polymorphism, a cornerstone
of OOP that allows for "one method name, different behaviors based on arguments."
Key Points:
Redefining Inherited Methods: Subclasses (derived classes) can override methods inherited
from their parent classes (base classes).
Signature Matching: The overriding method must have the same signature (name,
parameter list) as the overridden method.
Access Modifiers: Overridden methods can have different access modifiers (public, private,
protected) than the overridden method.
Virtual Keyword: The parent class method must be declared as virtual to allow overriding in
subclasses.
override Keyword: The subclass method uses the override keyword to explicitly indicate it's
overriding a parent class method.
Benefits:
o Flexibility: Code adapts to specific situa ons based on arguments provided.
o Reusability: Methods are wri en generically to handle various data types.
o Readability: Clear method names and overriding behavior enhance code clarity.
Diagram:
+--------------+
| Base Class | (Parent)
+--------------+
|
(Inherits) +--------------+
| | Sub Class 1 | (Child 1)
+--------------+ |
| +--------------+
| (Inherits) | Sub Class 2 | (Child 2)
+--------------+ |
+--------------+
| Sub Class N | (Child N)
+--------------+
- Overridden methods can exist in mul ple subclasses of the base class.
- Each subclass can poten ally have its own implementa on of the overridden method.
Code Example:
C#
class Shape
{
public virtual void Draw() // Virtual method for overriding
{
Console.WriteLine("Drawing a shape");
}
}
class Program
{
sta c void Main(string[] args)
{
Shape[] shapes = { new Circle(), new Square() };
foreach (Shape shape in shapes)
{
shape.Draw(); // Calls the appropriate Draw method based on object type at run me
(polymorphism)
}
}
}
Output:
Drawing a circle
Drawing a square
Explana on:
1. The Shape class defines a Draw() method declared as virtual. This allows subclasses to
override it.
2. The Circle and Square classes inherit from Shape.
3. Both Circle and Square override the Draw() method with their specific implementa on for
drawing a circle and a square, respec vely.
4. In the Main() method, an array of Shape objects holds instances of Circle and Square.
5. The foreach loop iterates through the shapes array.
6. When shape.Draw() is called, the run me determines the actual type of the object (Circle or
Square) and invokes the overridden method defined in that specific subclass. This
demonstrates polymorphism in ac on.
Key Differences from Method Overloading:
Feature Method Overriding Method Overloading
Signature Same name, same signature Same name, different signature
Loca on Subclass Same class
Inheritance Required Not required
Keyword override keyword used No special keyword needed
Purpose Redefine inherited behavior Provide mul ple func onali es
Polymorphism Enables dynamic polymorphism Enables sta c polymorphism
Export to Sheets
Addi onal Notes:
Method overriding is resolved at run me.
C# allows overriding constructors (special methods for object crea on) based on parameter
differences.
Overridden methods can call the overridden method using the base keyword.
Method Hiding in C#
Method Hiding (also known as Shadowing) allows you to redefine a method inherited from a base
class in a derived class, using the same name and signature (name and parameter list). However,
unlike Method Overriding, it's done without explicitly declaring the derived class method as override.
Key Points:
Redefining Inherited Methods: Derived classes can hide inherited methods from the base
class.
Signature Matching: The hidden method must have the same signature as the base class
method.
Access Modifiers: Visibility of the hidden method can be different from the base class
method.
No virtual or override Keywords: Unlike Overriding, neither virtual nor override keywords
are used.
Op onal new Keyword: While not strictly necessary, using new explicitly clarifies to the
compiler that you intend to hide the base class method.
Compiler Warning: Without the new keyword, the compiler will issue a warning about hiding
the base class method.
Diagram:
+--------------+
| Base Class | (Parent)
+--------------+
|
(Inherits) +--------------+
| | Derived Class | (Child)
+--------------+
|
| (Hides Methods)
Code Example:
C#
class Shape
{
public void Draw() // Base class method
{
Console.WriteLine("Drawing a shape");
}
}
class Program
{
sta c void Main(string[] args)
{
Shape[] shapes = { new Circle(), new Square() };
foreach (Shape shape in shapes)
{
shape.Draw(); // Calls the appropriate Draw method based on object type
}
}
}
Output:
Drawing a circle
Drawing a square
Explana on:
1. The Shape class defines a Draw() method.
2. The Circle class inherits from Shape.
3. The Circle class defines its own Draw() method with the new keyword, hiding the base class
method.
4. The Square class inherits from Shape and overrides the Draw() method using the override
keyword (op onal for non-abstract methods).
5. In the Main() method, an array of Shape objects holds instances of Circle and Square.
6. The foreach loop iterates through the shapes array.
7. When shape.Draw() is called, the run me determines the actual type of the object (Circle or
Square) and invokes the appropriate hidden or overridden method defined in that specific
subclass.
Key Differences from Method Overriding:
Feature Method Hiding Method Overriding
Signature Same name, same signature Same name, same signature
Loca on Derived class (without override) Derived class (with override)
Required (base class method must
Inheritance Not required
be virtual)
No special keyword needed (op onal
Keyword override keyword used
new)
Purpose Hide base class behavior Redefine base class behavior
Compiler Warning Warning if no new keyword No warning
Accessing Base Class Not directly accessible using derived Can be accessed using base
Method class instance keyword
Export to Sheets
When to Use Method Hiding:
You don't want the derived class to inherit the base class method behavior but want to keep
the same method name and signature.
You're working with legacy code where overriding wasn't used consistently.
You need to explicitly indicate that a method is intended to hide the base class method
(using new).
Considera ons:
Method hiding can make code less readable and maintainable as the base class method is no
longer directly accessible through the derived class instance.
Overriding is generally preferred as it maintains a clear rela onship between base and
derived class methods.
Par al Classes and Par al Methods in C#
Par al Classes
Concept: Allow you to split the defini on of a class across mul ple files.
Syntax: Use the par al keyword before the class declara on in each file.
Benefits:
o Improved Code Organiza on: Large classes can be divided into smaller, more
manageable units.
o Collabora on: Mul ple developers can work on different parts of a class
simultaneously.
o Code Genera on: Useful for code generated by tools like En ty Framework, where
you can add custom logic to auto-generated classes.
Example:
File 1: Employee.cs
C#
public par al class Employee
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
File 2: Employee.cs
C#
public par al class Employee
{
public double Salary { get; set; }
public void CalculateSalary()
{
// Calculate salary logic
}
}
Par al Methods
Concept: Allow you to define a method signature without an implementa on. The
implementa on can be provided in another part of the par al class.
Syntax:
o Declare the method with the par al keyword and void return type.
o Provide the implementa on of the par al method in another part of the par al
class.
Behavior:
o If the implementa on is not provided, the compiler removes the par al method and
all calls to it.
o Useful for op onal behavior or code genera on scenarios.
Example:
File 1: MyClass.cs
C#
public par al class MyClass
{
public void DoSomething()
{
Console.WriteLine("Doing something...");
LogEvent(); // Call to the par al method
}