0% found this document useful (0 votes)
6 views26 pages

C# 2nd Unit Notes

The document provides a comprehensive overview of classes and objects in C#, detailing how to define classes, declare methods, and use access modifiers. It explains the concepts of constructors, constant and read-only members, inheritance, and polymorphism, along with their types and differences. Additionally, it covers visibility control for UI elements and code elements, emphasizing the importance of access modifiers in C# programming.

Uploaded by

hemanthofc2022
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views26 pages

C# 2nd Unit Notes

The document provides a comprehensive overview of classes and objects in C#, detailing how to define classes, declare methods, and use access modifiers. It explains the concepts of constructors, constant and read-only members, inheritance, and polymorphism, along with their types and differences. Additionally, it covers visibility control for UI elements and code elements, emphasizing the importance of access modifiers in C# programming.

Uploaded by

hemanthofc2022
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

CLASSES AND OBJECTS IN C#:

Defining Class:

In C#, a class is a blueprint or a template for creating objects. It encapsulates data (fields and properties)
and behaviour (methods) into a single unit.

To create a class, use the class keyword.

Declaration of a Class

A class definition starts with the keyword class followed by the class name; and the class body enclosed by
a pair of curly braces.

<access specifier> class class_name

// member variables

<access specifier> <data type> variable1;

<access specifier> <data type> variable2; ...

<access specifier> <data type> variableN;

/ / member methods

<access specifier> <return type> method1(parameter_list)

// method body

<access specifier> <return type> method2(parameter_list)

// method body

...

<access specifier> <return type> methodN(parameter_list)

// method body

}
}

• Access specifiers specify the access rules for the members as well as the class itself. If not
mentioned, then the default access specifier for a class type is internal. Default access for the
members is private.

• Data type specifies the type of variable, and return type specifies the data type of the data the
method returns, if any.

• To access the class members, you use the dot (.) operator.

• The dot operator links the name of an object with the name of a member.

Adding members and methods:

• Fields and methods inside classes are often referred to as "Class Members".
• A method is a block of code that performs a specific task. It can take inputs, return results and is
defined within classes to make programs modular, readable and reusable.

Declaring a Method

The method signature consists of the method name and its parameter list. It uniquely identifies the
method within its class.

• Access Modifier: Defines the visibility of the method.

• Return Type: Specifies the type of value the method returns.

• Method Name: The name used to call the method.

• Parameters: A list of inputs the method can take and it is optional

• Method Body: The block of code that defines what the method does.

Syntax:

class ClassName

// Data members (fields)


datatype variableName;

// Method member

returntype MethodName()

// code

Ex:

using System;

class Student

// Members of the class

public int id; // data member

public string name; // data member

public void Show() // method member

[Link]("ID: " + id);

[Link]("Name: " + name);

class Program

static void Main()

Student s = new Student(); // create object

[Link] = 1; // adding value to members

[Link] = "Simraan";
[Link](); // calling member method

Member access modifiers:

• Access modifiers in C# define the scope and visibility of classes, methods, fields, constructors and
other members. They determine where and how a member can be accessed in a program.
• In C#, access modifiers are keywords that control the accessibility of types (like classes and
interfaces) and their members (like fields, methods, and properties). They determine which parts of
the code can access other parts, promoting encapsulation and data hiding.

[Link]: Members declared as public are accessible from anywhere, including other classes and
assemblies.

public class MyClass


{
public int PublicField;
public void PublicMethod() { /* ... */ }
}

[Link]: Members declared as private are accessible only within the class where they are defined. This is
the default access modifier if none is explicitly specified for a class member.

public class MyClass


{
private int PrivateField;
private void PrivateMethod() { /* ... */ }
}

[Link]: Members declared as protected are accessible within the class where they are defined and by
any classes derived from that class (through inheritance).

public class BaseClass


{
protected int ProtectedField;
}
public class DerivedClass : BaseClass
{
public void AccessProtected()
{
int value = ProtectedField; // Accessible in derived class
}
}

Accessing class members:

Accessing class members in C# depends on the member's accessibility level (defined by access modifiers)
and whether the member is static or an instance member.

1. Accessing Instance Members:

[Link] Members: The most common way to access members. If a field, property, or method is
declared public, you can access it directly using an instance of the class and the dot operator (.).

public class MyClass


{
public string PublicField;
public void PublicMethod() { /* ... */ }
}
// In another part of your code:
MyClass myObject = new MyClass();
[Link] = "Hello";
[Link]();

[Link] Members: private members are only accessible within the class they are declared in. To access or
modify them from outside the class, you typically provide public methods or properties (getters/setters) that
expose the private data in a controlled manner (encapsulation).

public class MyClass


{
private string _privateField;
public string GetPrivateField()
{
return _privateField;
}
public void SetPrivateField(string value)
{
_privateField = value;
}
}
// In another part of your code:
MyClass myObject = new MyClass();
[Link]("Secret");
string value = [Link]();

[Link] Members: protected members are accessible within the class and by derived classes.

[Link] Members: internal members are accessible within the same assembly.

[Link] Internal Members: Accessible within the same assembly and by derived classes (even in other
assemblies).

[Link] Protected Members: Accessible only within the same class and derived classes within the same
assembly.

2. Accessing Static Members:

• static members belong to the class itself, not to any specific instance. You access them directly
using the class name and the dot operator, without needing to create an object of the class.

public class MyClass


{
public static int StaticField;
public static void StaticMethod() { /* ... */ }
}
// In another part of your code:
[Link] = 10;
[Link]();

Constructors:

A constructor is a special method within a class that is automatically invoked when an instance (object) of
that class is created. Its primary purpose is to initialize the object's data members (fields) and perform any
necessary setup for the new object.

Key characteristics of constructors in C#:

[Link] Name as the Class: A constructor must have the exact same name as the class it belongs to.

[Link] Return Type: Unlike other methods, constructors do not have a return type, not even void.

[Link] Invocation: A constructor is called automatically when you use the new keyword to create an
object of the class.

[Link]: Constructors are typically used to assign initial values to fields, set up resources, or
perform other initialization logic.

[Link]: A class can have multiple constructors with different parameters (constructor overloading),
allowing for various ways to initialize an object.
[Link] Constructor: If you don't explicitly define any constructors in your class, the C# compiler
automatically provides a public, parameterless default constructor. This default constructor initializes
numeric fields to zero and reference types (like strings and other objects) to null.

Types of Constructors:

1. Default Constructor

2. Parameterized Constructor

3. Copy Constructor

4. Private Constructor

5. Static Constructor

1. Default Constructor :A default constructor in C# is a constructor with no parameters. It is


automatically provided by the compiler if no constructor is defined in the class. It initializes numeric
fields to 0, Boolean to false and reference types like strings or objects to null.

2. Parameterized Constructor

A constructor having at least one parameter is called a parameterized constructor. It can initialize each
instance of the class to different values.

3. Copy Constructor

A copy constructor is used to create a new object by copying the values from an existing object of the same
class. Useful when you need to duplicate an object or create a new object based on the state of another.

4. Private Constructor

If a constructor is created with a private specifier is known as Private Constructor. It is not possible for
other classes to derive from this class and also it’s not possible to create an instance of this class. Some
important points regarding the topic is mentioned below:

• It is the implementation of a singleton class pattern.

• Use a private constructor when we have only static members.

• Using a private constructor prevents the creation of the instances of that class.

5. Static Constructor

Static Constructor has to be invoked only once in the class and it has been invoked during the creation of
the first reference to a static member in the class. A static constructor is initialized static fields or data of
the class and is to be executed only once.

• It can’t be called directly.


• When it is executing then the user has no control.

• It does not take access modifiers or any parameters.

• It is called automatically to initialize the class before the first instance is created.

Constant members and read only members:

both const (constant members) and readonly (read-only members) are used to declare fields whose values
cannot be changed after initialization. However, they differ in when and how their values are assigned and
evaluated.

Constant Members (const):

• Compile-time constants: The value of a const field must be known and assigned at compile time. It
must be a literal value or another const expression.

• Initialization: A const field must be initialized at the point of its declaration.

• Static by nature: const fields are implicitly static, meaning they belong to the type itself, not to an
instance of the type. You cannot explicitly use the static modifier with const.

• Limited types: Only built-in value types (like int, double, bool, string, enum) and null for reference
types can be declared as const.

Example:

public class MyClass


{
public const int DaysInWeek = 7;
public const string CompanyName = "Acme Corp";
}

Read-Only Members (readonly)

• Runtime constants: The value of a readonly field can be assigned either at the point of declaration
or within the class constructor(s). This allows for values that are determined at runtime, such as
values loaded from configuration files or calculated based on constructor parameters.

• Initialization: Can be initialized at declaration or in the constructor.

• Instance or static: readonly fields can be either instance-level (default) or static. You can explicitly
use the static modifier with readonly.

• Any type: readonly fields can be of any data type, including reference types.

Example:
public class MyClass
{
public readonly int MaxUsers;
public static readonly string DatabaseConnectionString;

public MyClass(int maxUsers)


{
MaxUsers = maxUsers;
}

static MyClass()
{
DatabaseConnectionString = "Data Source=server;Initial Catalog=mydb;"; // Value determined at
runtime
}
}

Key Differences Summarized:

Feature const readonly

Evaluation Compile-time Runtime

Initialization Only at declaration At declaration or in constructor(s)

Static Implicitly static (cannot use static) Can be instance or static (can use static)

Allowed Types Built-in value types, string, enum Any type

Inheritance and Polymorphism:

Inheritance is one in which a new class is created that inherits the properties of the already exist class. It
supports the concept of code reusability and reduces the length of the code in object-oriented programming.

Types of Inheritance are:

1. Single inheritance

2. Multi-level inheritance
3. Multiple inheritances

4. Hybrid inheritance

5. Hierarchical inheritance

Here, class B is the derived class which inherit the property(add method) of the base class A.

Polymorphism:
Polymorphism is that in which we can perform a task in multiple forms or ways. It is applied to the
functions or methods. Polymorphism allows the object to decide which form of the function to implement
at compile-time as well as run-time.

Types of Polymorphism are:

1. Compile-time polymorphism (Method overloading)

2. Run-time polymorphism (Method Overriding)

Difference between Inheritance and Polymorphism:

[Link] Inheritance Polymorphism

Inheritance is one in which a


new class is created (derived Whereas polymorphism is that
1. class) that inherits the features which can be defined in
from the already existing multiple forms.
class(Base class).

Whereas it is basically applied


2. It is basically applied to classes.
to functions or methods.

Polymorphism allows the object


Inheritance supports the concept
to decide which form of the
of reusability and reduces code
3. function to implement at
length in object-oriented
compile-time (overloading) as
programming.
well as run-time (overriding).

Inheritance can be single, Whereas it can be compiled-


4. hybrid, multiple, hierarchical time polymorphism (overload)
and multilevel inheritance. as well as run-time
[Link] Inheritance Polymorphism

polymorphism (overriding).

While it is also used in pattern


5. It is used in pattern designing.
designing.

Example :
Example :
The class bike can have method
The class bike can be inherit
name set_color(), which
6. from the class of two-wheel
changes the bike's color based
vehicles, which is turn could be
on the name of color you have
a subclass of vehicles.
entered.

Defining subclass:

A subclass (also known as a derived class or child class) is defined by inheriting from an existing class
(known as a superclass, base class, or parent class). This process is called inheritance and is achieved using
the colon (:) operator.

Syntax for Defining a Subclass:

class DerivedClass : BaseClass


{
// Members (fields, properties, methods, etc.) specific to the derived class
}

Explanation:

• class DerivedClass: This declares the new class you are creating, which will be the subclass.

• : (Colon Operator): This signifies inheritance.

• BaseClass: This is the name of the existing class from which DerivedClass will inherit.

Key Points about C# Subclasses:

• Single Inheritance: C# supports single inheritance, meaning a class can directly inherit from only
one base class.

• Access Modifiers: Subclasses can access public and protected members of their base
class. private members are not inherited and cannot be directly accessed by the subclass.
• [Link]: All classes in C# implicitly inherit from the [Link] class.

• Method Overriding: Subclasses can provide their own implementation for virtual methods defined
in the base class using the override keyword.

• Constructors: Subclasses do not inherit constructors from the base class but can call base class
constructors using the base keyword.

Visibility control:

1. UI Element Visibility (e.g., in Windows Forms or WPF):

This controls whether a visual element, such as a button, textbox, or panel, is displayed to the user.

• Visible Property: The most common way to control UI element visibility in Windows Forms is
through the Visible property, which is a boolean. Setting [Link] = true; makes the
control and its child controls visible, while [Link] = false; hides them.

// Example in a Windows Forms application


private void buttonToggleVisibility_Click(object sender, EventArgs e)
{
// Toggle the visibility of a textbox
[Link] = ![Link];
}

• Visibility Property (WPF/UWP): In WPF and Universal Windows Platform (UWP) applications,
the Visibility property is used, and it takes values from the Visibility enumeration:

o [Link]: The element is displayed.

o [Link]: The element is hidden, but it still occupies space in the layout.

o [Link]: The element is hidden and does not occupy any layout space.

2. Code Element Visibility (Access Modifiers):

This controls the accessibility of classes, methods, properties, and fields within your C# code. Access
modifiers determine which parts of your code (or other assemblies) can interact with these elements.

• public: Accessible from any code in any assembly.

• private: Accessible only within the class or struct in which it is declared.

• protected: Accessible within the class in which it is declared and by derived classes.

• internal: Accessible only within the same assembly.

• protected internal: Accessible within the same assembly or by derived classes in other assemblies.
• private protected: Accessible within the same assembly and by derived classes within the same
assembly.

• file: (C# 11 and later) Accessible only within the same source file.

// Example of access modifiers


public class MyClass
{
public int PublicField;
private string PrivateField;
protected void ProtectedMethod() { /* ... */ }
internal decimal InternalProperty { get; set; }
}

Sub class constructors:

A subclass constructor in C# is responsible for initializing the fields and properties of the subclass, and it
must also ensure that the base class (or parent class) is initialized before its own initialization completes.
This is achieved by explicitly or implicitly calling a base class constructor.

Calling Base Class Constructors:

• Implicit Call: If a derived class constructor does not explicitly call a base class constructor, the
parameterless constructor of the immediate base class is implicitly called. If the base class does not
have a parameterless constructor, a compile-time error will occur.

Ex:

class BaseClass

public BaseClass()

[Link]("BaseClass parameterless constructor called.");

class DerivedClass : BaseClass

public DerivedClass()
{

[Link]("DerivedClass parameterless constructor called.");

• Explicit Call using base keyword: To call a specific base class constructor (especially a
parameterized one), the base keyword is used in the derived class constructor's initializer list.

Ex: class BaseClass

public BaseClass(string message)

[Link]($"BaseClass constructor with message: {message} called.");

class DerivedClass : BaseClass

public DerivedClass(string derivedMessage, string baseMessage) : base(baseMessage)

[Link]($"DerivedClass constructor with message: {derivedMessage} called.");

Multilevel inheritance:

Multilevel Inheritance occurs when a derived class is formed from another derived class.
Ex:

using System;

class Vehicle

public void Start()

[Link]("Vehicle is starting...");

class Car : Vehicle // Car inherits Vehicle

public void Drive()

[Link]("Car is driving...");

class SportsCar : Car // SportsCar inherits Car

public void Turbo()


{

[Link]("SportsCar turbo mode ON!");

class Program

static void Main()

SportsCar sc = new SportsCar();

[Link](); // from Vehicle

[Link](); // from Car

[Link](); // from SportsCar

Method overriding:

Method overriding is a mechanism that allows a derived class to provide a specific implementation for a
method that is already defined in its base class. This is a core concept of runtime polymorphism in object-
oriented programming.

using System;

class Vehicle

public virtual void Show()

[Link]("This is a vehicle");

class Car : Vehicle

{
public override void Show()

[Link]("This is a car");

class Program

static void Main()

Vehicle v = new Vehicle();

[Link](); // base class method

Vehicle c = new Car();

[Link](); // overridden method in Car

Abstract classes:

An abstract class is a class that cannot be instantiated directly. Abstract classes are used when we want to
define a common template for a group of related classes but leave some methods or properties to be
implemented by derived classes.

• An abstract class cannot be directly instantiated. We can only create objects of derived classes.

• Abstract methods are declared in the abstract classes but do not have implementation, derived
classes are required to implement them.

• An abstract class also contains properties and fields which can be accessed by derived classes.

using System;

abstract class Shape // abstract class

public abstract void Draw(); // abstract method


}

class Circle : Shape // class extending Shape

public override void Draw()

[Link]("Drawing a Circle");

}s

class Program

static void Main()

Shape s = new Circle(); // object using base reference

[Link]();

Operation Polymorphism:

Polymorphism is a fundamental concept in object-oriented programming that allows objects to take on


"many forms." It enables a single interface, such as a method or property, to behave differently depending
on the specific type of object it is invoked upon. This allows for more flexible, reusable, and maintainable
code.

There are two main types of polymorphism in C#: Compile-time Polymorphism (Method Overloading).

This occurs when multiple methods within the same class share the same name but have different
signatures (different numbers or types of parameters). The compiler determines which method to call based
on the arguments provided during the method call.

public class Calculator


{
public int Add(int a, int b)
{
return a + b;
}

public double Add(double a, double b)


{
return a + b;
}
}

Run-time Polymorphism (Method Overriding).

This occurs in an inheritance hierarchy where a derived class provides a specific implementation for a
method that is already defined in its base class. This is achieved using the virtual keyword in the base class
method and the override keyword in the derived class method. When a method is called on an object of the
derived class through a base class reference, the derived class's implementation is executed.

public class Animal


{
public virtual void MakeSound()
{
[Link]("The animal makes a sound.");
}
}

public class Dog : Animal


{
public override void MakeSound()
{
[Link]("The dog barks.");
}
}

public class Cat : Animal


{
public override void MakeSound()
{
[Link]("The cat meows.");
}
}

Interfaces- implementing interfaces Delegates- Delegate declaration:


An interface in C# defines a contract specifying a set of members (methods, properties, events, indexers)
that a class or struct must implement. It outlines what a type can do, without specifying how.

Implementing an Interface:

To implement an interface, a class or struct declares that it implements the interface using the colon (:)
syntax, followed by the interface name. The class or struct must then provide an implementation for all the
members defined in that interface.

Code

public interface IMyInterface


{
void MyMethod();
int MyProperty { get; set; }
}

public class MyClass : IMyInterface


{
public int MyProperty { get; set; } // Implementation of MyProperty

public void MyMethod() // Implementation of MyMethod


{
// Method logic here
[Link]("MyMethod implemented in MyClass.");
}
}

Delegates: Delegate Declaration in C#

A delegate in C# is a type-safe function pointer. It holds references to methods and allows you to pass
methods as arguments to other methods, or to manage a group of methods as a single entity (e.g., in event
handling).

Declaring a Delegate:

A delegate is declared using the delegate keyword, specifying its return type and parameter list, which
defines the signature of the methods it can point to.

public delegate void MyDelegate(string message);

This declaration defines a delegate named MyDelegate that can point to any method that: Returns void and
Takes a single string parameter.
Using a Delegate:

You can then create instances of the delegate and assign methods to them.

Code

public class MyClassWithMethods


{
public void DisplayMessage(string msg)
{
[Link]($"Message: {msg}");
}

public void LogMessage(string msg)


{
[Link]($"Logging: {msg}");
}
}

// In another part of your code


MyClassWithMethods obj = new MyClassWithMethods();

MyDelegate delegateInstance = new MyDelegate([Link]);


delegateInstance += [Link]; // Adding another method (multicast delegate)

delegateInstance("Hello Delegates!");

Delegate methods:

1. Invoke()

Used to call the method that the delegate refers to.

delegate void MyDel();

static void Show()

[Link]("Hello");

}
static void Main()

MyDel d = Show;

[Link](); // calls Show()

2. BeginInvoke()

Starts the delegate asynchronously (non-blocking call).

IAsyncResult r = [Link](null, null);

3. EndInvoke()

Ends the asynchronous call started by BeginInvoke().

[Link](r);

DELEGATE PROPERTIES

4. Method

Returns the method information (name, return type, etc.)

[Link]([Link]);

5. Target

Returns the object instance on which the method is called.

[Link]([Link]);

Delegate instantiation:

Use the new keyword to instantiate a delegate. When creating a delegate, the argument passed to the new
expression is written similar to a method call, but without the arguments to the method.

For example −

public delegate void printString(string s);

printString ps1 = new printString(WriteToScreen);

Delegate invocation:

In C#, invoking a delegate means executing the method or methods that the delegate instance refers
to. Delegates act as type-safe function pointers, allowing you to treat methods as objects and pass them
around.
Steps for Delegate Invocation:

• Declare the Delegate: Define the delegate type, specifying its return type and parameter
signature. This signature must match the methods it will point to.

Code

public delegate int MyDelegate(int x, int y);

• Create a Method (or methods) to be Invoked: Implement the method(s) that will be associated with
the delegate. The method's signature must match the delegate's signature.

Ex:

public static int Add(int a, int b)


{
return a + b;
}

public static int Multiply(int a, int b)


{
return a * b;
}

• Instantiate and Assign the Delegate: Create an instance of the delegate and associate it with a
specific method.

Ex:

MyDelegate del = Add; // Assigns the 'Add' method to the delegate

You can also use lambda expressions for simpler assignments:

Ex:

MyDelegate del2 = (a, b) => a * b; // Assigns a lambda expression to the delegate

• Invoke the Delegate: Call the delegate instance as if it were a method, passing the required
arguments.

Ex:

int result1 = del(5, 3); // Invokes the 'Add' method, result1 will be 8
int result2 = del2(5, 3); // Invokes the lambda expression, result2 will be 15

You can also explicitly use the Invoke() method:

Ex:
int result3 = [Link](10, 2); // Invokes the 'Add' method, result3 will be 12

Multicast Delegates:

Delegates can also hold references to multiple methods, forming an "invocation list." When a multicast
delegate is invoked, all methods in its invocation list are called in the order they were added.

Ex:

MyDelegate multicastDel = Add;


multicastDel += Multiply; // Adds 'Multiply' to the invocation list
multicastDel += (a, b) => a - b; // Adds another method (lambda)

// When invoked, all three methods will be called in sequence.


// If the delegate has a return value, it will be the return value of the *last* method invoked.
int finalResult = multicastDel(10, 5); // finalResult will be 5 (from the subtraction)

Important Considerations:

• NullReferenceException:

If you attempt to invoke a delegate that has no methods assigned to it (i.e., it's null),
a NullReferenceException will occur. A common pattern to prevent this is to use the null-conditional
operator (?.) before invoking: del?.Invoke(x, y);

• Return Values and Out Parameters:

In a multicast delegate, if the delegate has a return value or out parameters, the value returned will be from
the last method in the invocation list.

• Exceptions:

If a method in a multicast delegate's invocation list throws an unhandled exception, the subsequent methods
in the list will not be executed.

Managing errors and exceptions:

In C#, managing errors and exceptions is primarily handled through structured exception handling
using try, catch, and finally blocks.

1. try Block:

• The try block encloses the code that might potentially throw an exception.

• If an exception occurs within the try block, the normal flow of execution is interrupted, and control
is transferred to an appropriate catch block.

2. catch Block(s):
• A catch block follows a try block and is designed to handle specific types of exceptions.

• You can have multiple catch blocks to handle different exception types. The most specific exception
type should be caught first, followed by more general ones.

• A general catch (Exception ex) block can catch any unhandled exception, but it is generally
recommended to catch specific exceptions for better error management and more informative
feedback.

• Inside the catch block, you can implement logic to handle the exception, such as logging the error,
displaying a user-friendly message, or attempting to recover from the error.

3. finally Block:

• The finally block is optional and follows the try and catch blocks.

• Code within the finally block is guaranteed to execute, regardless of whether an exception occurred
or was handled.

• It is commonly used for cleanup tasks, such as closing file streams, database connections, or
releasing other resources that were opened in the try block.

Example of try-catch-finally:

try
{
// Code that might throw an exception
int result = 10 / 0; // This will cause a DivideByZeroException
[Link]("This line will not be executed if an exception occurs.");
}
catch (DivideByZeroException ex)
{
// Handle the specific DivideByZeroException
[Link]($"Error: Cannot divide by zero. Details: {[Link]}");
}
catch (Exception ex)
{
// Handle any other unexpected exceptions
[Link]($"An unexpected error occurred. Details: {[Link]}");
}
finally
{
// Cleanup code that always executes
[Link]("Cleanup operations complete.");
}

Additional Considerations:

• Throwing Exceptions:

You can explicitly throw exceptions using the throw keyword to signal an error condition from your
methods.

• Custom Exceptions:

You can define your own custom exception types by inheriting from [Link] to represent
application-specific error conditions.

• Exception Filtering (C# 6.0+):

You can add a when clause to a catch block to specify a condition that must be true for the catch block to
execute, providing more granular control over exception handling.

• Logging:

Integrate a logging framework to record exception details for debugging and monitoring in production
environments.

• Avoid Swallowing Exceptions:

Do not catch exceptions and do nothing with them, as this can mask underlying issues and make debugging
difficult. If you catch an exception and cannot fully handle it, consider re-throwing it or wrapping it in a
more specific custom exception.

You might also like