C# Programming and .NET Framework Guide
C# Programming and .NET Framework Guide
NOTES
553/23/M05
Structure of a C# Program:
A typical C# program follows a structured format, consisting of various elements:
✓ Comments: Comments are non-executable lines used to provide information about the
code. They help in understanding the code's purpose and functionality. Comments in C
can be single-line (//) or multi-line (/ /).
✓ Using Directive: The using directive is used to include namespaces in the program. It
simplifies the code by allowing the use of types in a namespace without fully qualifying
them.
✓ Namespace: A namespace is a logical grouping mechanism used to organize related code
elements, such as classes, interfaces, and other namespaces. It helps in avoiding naming
conflicts and provides better code organization.
✓ Class Definition: A class is a blueprint for creating objects in C. It encapsulates data
(attributes) and behavior (methods) related to a specific entity or concept. Classes are the
fundamental building blocks of C programs.
✓ Main() Method: The Main method is the entry point of a C program. It serves as the
starting point for program execution. The Main method is typically located within a class
and is declared with the static modifier and void return type.
✓ Method Body Statements: Method body statements contain the actual code that performs
specific tasks within the program. These statements are enclosed within curly braces {}
and are executed sequentially.
1|Pa ge
Scax the one
Visual Studio IDE:
Visual Studio is an integrated development environment (IDE) developed by Microsoft for building
software applications. It provides a comprehensive set of tools and features for writing, debugging,
and testing code. Visual Studio supports various programming languages, including C, C++, and
Visual Basic.
Debugging an Application:
Debugging is the process of identifying and fixing errors or bugs in a program. In C, errors can be
classified into three main types: syntax errors, runtime errors, and logical errors. Syntax errors occur
due to incorrect syntax in the code and are detected by the compiler. Runtime errors occur during
program execution and can cause the program to terminate unexpectedly. Logical errors, also known
as bugs, occur when the program does not behave as intended.
To debug an application in Visual Studio, you can use various debugging tools and techniques, such
as setting breakpoints, stepping through code, inspecting variables, and handling exceptions. The
debugging process involves identifying the cause of the error, understanding its impact on the
program's behaviour, and applying appropriate fixes to resolve it.
1. Placing the code that may throw exceptions within a try block.
2. Catching and handling exceptions in one or more catch blocks.
3. Optionally, using finally blocks to execute clean-up code, regardless of whether an exception
occurs.
By properly handling errors, you can improve the robustness and reliability of your C applications,
ensuring that they gracefully handle unexpected conditions and provide a better user experience.
2|Pa ge
Scax the one
1. .NET Framework (Classic): This is the original implementation of the .NET Framework, designed
for building Windows desktop applications, web applications, and services. It runs primarily on
Windows operating systems and is tightly integrated with Windows APIs.
2. .NET Core: Introduced as a cross-platform and open-source implementation of the .NET
Framework, .NET Core supports building and running applications on Windows, macOS, and Linux.
It offers improved performance, scalability, and modularity compared to the classic .NET Framework.
.NET Core is suitable for building cloud-native and containerized applications.
3. .NET 5 and later: Microsoft unified the .NET ecosystem by merging .NET Core, .NET Framework,
and Xamarin into a single platform called .NET 5. Subsequent versions, such as .NET 6, .NET 7, and
so on, continue this unified approach. .NET 5 and later versions support cross-platform development
for a wide range of application types, including desktop, web, mobile, cloud, and IoT.
Components of the .NET Framework Architecture:
Disadvantages:
✓ Windows Dependency: The classic .NET Framework is tightly integrated with Windows,
limiting its cross-platform capabilities compared to .NET Core and later versions.
✓ Memory Consumption: .NET applications may consume more memory compared to native
applications due to the overhead of the CLR and runtime environment.
3|Pa ge
Scax the one
✓ Learning Curve: While the .NET Framework offers a rich set of features, mastering its entire
ecosystem may require time and effort, especially for beginners or developers transitioning
from other platforms.
✓ Performance Overhead: Although improvements have been made in recent versions, .NET
applications may still have performance overhead compared to native code execution,
particularly in high-performance computing scenarios.
✓ Vendor Lock-In: While .NET Core and later versions offer cross-platform support, the classic
.NET Framework is primarily designed for Windows environments. This can lead to vendor
lock-in for applications targeting the classic framework, limiting deployment options and
flexibility.
✓ Community and Third-Party Support: While the .NET ecosystem has a large and active
community, it may not be as extensive as other development ecosystems like Java or
JavaScript. This can result in fewer third-party libraries, tools, and resources available for
.NET developers, although this gap has been narrowing over time.
✓ Tooling Ecosystem: While Visual Studio is a powerful IDE for .NET development, its full
feature set may not be available on all platforms, particularly for non-Windows environments.
This can impact the developer experience and productivity for developers working on macOS
or Linux.
Overall, while the .NET Framework offers many advantages for building a wide range of applications,
it's essential to consider the specific requirements and constraints of your project when choosing
between different .NET implementations. Additionally, the ongoing evolution of the .NET ecosystem,
with initiatives like .NET 5 and later versions, aims to address many of the limitations of previous
iterations, making .NET a compelling choice for modern application development.
Object
An object is an instance of a class. It represents a specific occurrence or entity based on the class's
blueprint. Objects have state (defined by the class's properties) and behaviour (defined by the class's
methods). For example, if `Car` is a class, an object of type `Car` could be created with specific
attributes like `Make = "Toyota"`, `Model = "Camry"`, and `Year = 2022`.
4|Pa ge
Scax the one
Explaining Constructor and Destructor in C#:
Constructor
A constructor is a special method in a class that is automatically called when an object of that class is
created. Its primary purpose is to initialize the object's state, such as setting initial property values or
performing other setup tasks. Constructors have the same name as the class and may have parameters
to customize the object's initialization. In C, constructors can be overloaded, allowing multiple
constructors with different parameter lists.
Destructor
In C#, destructors are rarely used because the .NET runtime automatically manages memory
allocation and deallocation through garbage collection. However, C does support destructors, which
are special methods with the same name as the class preceded by a tilde (`~`). Destructors are called
when an object is about to be destroyed or garbage collected. They are used to release unmanaged
resources held by an object, such as file handles or network connections. It's important to note that
unlike constructors, destructors cannot be overloaded or have parameters.
Public: Members with the `public` access specifier are accessible from any other code in the same
assembly or in other assemblies that reference the assembly containing the member. This is the most
permissive access level.
Private :Members with the `private` access specifier are accessible only within the same class or
struct. They cannot be accessed from outside the containing type.
Protected: Members with the `protected` access specifier are accessible within the same class or
struct, as well as by derived classes (classes that inherit from the containing type), whether they are in
the same assembly or a different assembly.
Internal: Members with the `internal` access specifier are accessible only within the same assembly.
They cannot be accessed from outside the assembly, even by derived classes.
Protected Internal: Members with the `protected internal` access specifier are accessible within the
same assembly and by derived classes, regardless of whether they are in the same assembly or a
different assembly.
Inheritance
Inheritance is a mechanism in OOP that allows a class (called a derived class or subclass) to inherit
properties and behaviors from another class (called a base class or superclass). The subclass can reuse
and extend the functionality of the superclass, thereby promoting code reuse and establishing a
hierarchical relationship between classes. Inheritance facilitates the creation of specialized classes that
inherit common attributes and methods from a more general superclass.
Polymorphism
Polymorphism is the ability of objects to take on different forms or behaviors depending on their
context. In OOP, polymorphism allows objects of different classes to be treated as objects of a
common superclass, enabling code to work with objects at a higher level of abstraction. There are two
types of polymorphism:
Static Polymorphism
Also known as compile-time polymorphism, static polymorphism is achieved through method
overloading and operator overloading. Method overloading allows multiple methods with the same
name but different parameter lists to coexist within the same class, while operator overloading enables
custom operators to be defined for user-defined types.
Dynamic Polymorphism
Also known as runtime polymorphism, dynamic polymorphism is achieved through method
overriding and virtual functions. Method overriding allows a subclass to provide a specific
implementation of a method that is already defined in its superclass. Virtual functions are declared in
the base class and can be overridden by derived classes, enabling late binding or dynamic dispatch of
method calls based on the actual type of the object at runtime.
In C#, you can apply inheritance, encapsulation, and polymorphism to solve various programming
problems and build robust, maintainable software solutions. Here's how you can use these concepts in
C programs:
6|Pa ge
Scax the one
Inheritance: Define base classes with common properties and methods, and derive specialized
classes from them to inherit and extend their functionality. Use the `class` keyword to define classes
and the `: baseClassName` syntax to specify inheritance.
Encapsulation: Encapsulate data by declaring class fields as private and providing public properties
or methods to access and modify the data. Use access modifiers (`public`, `private`, `protected`,
`internal`, etc.) to control the visibility and accessibility of class members.
Polymorphism: Implement method overriding in derived classes to provide specialized behavior
while adhering to the contract defined in the base class. Use the `override` keyword to override base
class methods in derived classes. Additionally, use interfaces and abstract classes to achieve
polymorphic behavior through interface implementation and method overriding.
By effectively utilizing inheritance, encapsulation, and polymorphism, you can design flexible,
modular, and extensible C programs that are easier to maintain and scale over time. These object-
oriented principles promote code reuse, abstraction, and separation of concerns, leading to cleaner and
more organized codebases.
7|Pa ge
Scax the one
Event Subscribing: Event subscribing involves registering event handlers (methods) with an event.
Subscribers indicate interest in receiving notifications when a specific event occurs. In C#, event
subscribing is achieved by adding event handler methods to the event's invocation list using the `+=`
operator.
Creating Graphical User Interface (GUI) for Applications that Responds to User
Events:
In C#, you can create GUI applications using frameworks like Windows Forms (WinForms) or
Windows Presentation Foundation (WPF). These frameworks provide graphical controls (such as
buttons, text boxes, and menus) that users can interact with, generating events in response to their
actions (such as clicking a button or typing in a text box). By handling these events using event-driven
programming techniques, you can create responsive and interactive GUI applications in C.
Branching: Branching is a version control technique where you create a separate line of
development from the main codebase. Branches allow you to work on new features or bug fixes
without affecting the main codebase. In Visual Studio, you can create branches using Git, allowing for
parallel development and experimentation.
Merging: Merging is the process of combining changes from one branch into another. In Visual
Studio, you can merge branches using Git to incorporate changes made in separate branches back into
the main codebase. Merging ensures that all changes are integrated seamlessly and conflicts are
resolved appropriately.
Version Control: Version control systems like Git enable you to track changes to your codebase
over time, including who made the changes and when they were made. Visual Studio provides built-in
support for Git, allowing you to commit changes, view commit history, and manage branches directly
within the IDE. This integration streamlines the development workflow and ensures that your project
remains organized and well-managed.
Version Control Benefits: Integrating version control into your Visual Studio projects offers
several benefits. It provides a centralized repository for your codebase, allowing multiple developers
to collaborate effectively on the same project. Version control also facilitates code review, rollback to
previous versions, and branching for parallel development. Additionally, version control systems
track changes, providing a history of modifications made to the codebase over time.
Committing Changes: In Visual Studio, you can commit changes to your codebase using Git.
When you commit changes, you create a snapshot of the current state of your project, including
8|Pa ge
Scax the one
modifications to files, additions, and deletions. Each commit is accompanied by a commit message
that describes the changes made, providing context for future reference.
Viewing Commit History: Visual Studio allows you to view the commit history of your project,
showing a chronological list of commits along with their associated commit messages. You can
navigate through the commit history to understand when changes were made, who made them, and the
specific modifications included in each commit. This visibility into the project's history aids in
understanding the evolution of the codebase and tracking down issues.
Managing Branches: Branching is a powerful feature of version control systems that allows you to
create separate lines of development within your project. In Visual Studio, you can create and manage
branches using Git, enabling parallel development of new features, bug fixes, or experiments.
Branches provide isolation for changes, allowing developers to work independently without
interfering with the main codebase. Once development is complete, branches can be merged back into
the main branch using Visual Studio's merge tools.
By integrating source control into your Visual Studio projects and utilizing version control features
like branching, merging, and commit tracking, you can streamline your development workflow,
improve collaboration among team members, and ensure the integrity and traceability of your
codebase. Additionally, source control integration in Visual Studio enhances project management
capabilities, enabling efficient code review, issue tracking, and project auditing.
Console Input and Output: Console applications interact with users through the console window.
They use `[Link]()` to display output to the console and `[Link]()` to read
input from the user.
Simple Structure: Console applications often have a simple structure, focusing on sequential
execution of code without user interfaces. They are commonly used for command-line tools, utilities,
or basic text-based applications.
9|Pa ge
Scax the one
Design-Time and Run-Time Views: Windows Forms applications have both design-time and run-
time views. At design time, developers use visual designers in IDEs like Visual Studio to layout forms
and add controls. At run time, the application executes, and users interact with the forms and controls.
MVVM (Model-View-ViewModel) Pattern: WPF applications often follow the MVVM pattern,
which separates the UI logic (View) from the application logic (ViewModel) and the data (Model).
This separation of concerns promotes maintainability, testability, and code reusability.
Rich User Interface: WPF applications offer a rich and flexible user interface, with support for
advanced graphics, animations, styling, templating, and data binding. Developers can create visually
appealing and interactive applications using WPF's powerful features.
Creating a WPF application project in C# provides developers with a modern and versatile platform
for building desktop applications with rich user interfaces and seamless integration of data and
controls. WPF's flexible architecture and support for MVVM enable developers to create maintainable
and scalable applications that meet the needs of modern software development.
Comments: Comments in C are used to provide explanations and documentation within the code.
They are ignored by the compiler and serve to improve code readability and maintainability.
Comments can be single-line (`//`) or multi-line (`/ /`).
Using Directive: The `using` directive in C is used to include namespaces in the program. It
simplifies code by allowing the use of types in a namespace without fully qualifying them.
Namespace: A namespace is a logical grouping mechanism used to organize related code elements,
such as classes, interfaces, and other namespaces. It helps in avoiding naming conflicts and provides
better code organization.
Main() Method: The `Main` method is the entry point of a C program. It serves as the starting point
for program execution. The `Main` method is typically located within a class and is declared with the
`static` modifier and `void` return type.
Identifiers in C#: Identifiers are names given to various program elements, such as variables,
methods, classes, etc.
10 | P a g e
Scax the one
✓ Must start with a letter or underscore (`_`), followed by letters, digits, or underscores.
✓ Cannot contain spaces or special characters (except underscores).
✓ Cannot be a reserved keyword.
Variables and Constants: Variables are used to store data temporarily during program execution,
while constants are used to store values that remain constant throughout the program's execution. In
C, variables are declared using a data type followed by an identifier, while constants are declared
using the `const` keyword.
Operators and Expressions in C: Operators are symbols used to perform operations on operands,
such as arithmetic, logical, and relational operations. Expressions are combinations of operands and
operators that evaluate to a single value. C supports a wide range of operators and expressions for
manipulating data and performing computations.
Testing C# Programs: Testing is an essential part of the software development process, ensuring that
the code behaves as expected and meets the specified requirements. In C, testing can be performed
using various techniques and frameworks:
Unit Testing: Unit testing involves testing individual units or components of the code in isolation.
Frameworks like NUnit, MSTest, or xUnit can be used to write and execute unit tests in C.
Mocking Objects and Dependencies: Mocking frameworks like Moq allow developers to create
mock objects and simulate the behavior of dependencies during testing, enabling thorough testing of
code under different scenarios.
Test-Driven Development (TDD): TDD is a development approach where tests are written before
the code is implemented. Developers write failing tests that describe the desired behavior, implement
the code to make the tests pass, and then refactor the code as needed while ensuring that all tests pass.
Unit Testing: Unit testing involves testing individual units or components of the code in isolation.
Frameworks like NUnit, MSTest, or xUnit can be used to write and execute unit tests in C. These
frameworks provide features for organizing tests, defining test cases, and asserting expected
outcomes.
Mocking Objects and Dependencies: In complex applications, components often rely on other
objects or services. Mocking frameworks like Moq allow developers to create mock objects and
simulate the behavior of dependencies during testing. This enables thorough testing of code under
different scenarios without relying on actual implementations of dependencies.
11 | P a g e
Scax the one
Test-Driven Development (TDD): Test-driven development (TDD) is a development approach
where tests are written before the code is implemented. Developers write failing tests that describe the
desired behavior, implement the code to make the tests pass, and then refactor the code as needed
while ensuring that all tests pass. TDD promotes a test-first mindset and helps ensure that code is
thoroughly tested from the outset.
By incorporating these testing practices into the development process, developers can identify and fix
issues early, improve code quality, and build more reliable and maintainable software solutions.
Testing helps ensure that the code behaves as expected, meets the specified requirements, and remains
resilient to changes and updates.
User Experience (UX): UX encompasses the overall experience of users when interacting with a
product or system, including aspects such as usability, accessibility, and satisfaction. It considers the
entire user journey, from initial interaction to task completion, and seeks to optimize the experience to
meet user needs and expectations effectively.
Usability and User Experience (UX): Usability is crucial for ensuring that users can navigate and
interact with the interface easily and efficiently. UX design focuses on understanding user needs,
behaviors, and preferences to create a seamless and enjoyable experience.
Interaction Design: Interaction design involves designing interactive elements, such as buttons,
forms, and navigation menus, to provide clear feedback and affordances. It emphasizes usability,
consistency, and predictability in user interactions.
Branding and Visual Identity: Incorporating branding elements, such as logos, colors, and
typography, helps establish a cohesive visual identity for the application. Consistent branding creates
brand recognition and reinforces the application's identity.
Information Architecture: Information architecture involves organizing and structuring content
within the interface to facilitate navigation and comprehension. Clear information architecture
improves usability and helps users find the information they need quickly and efficiently.
12 | P a g e
Scax the one
Motion Design: Motion design adds dynamism and interactivity to the interface through animations,
transitions, and micro-interactions. Thoughtful motion design enhances the user experience by
providing feedback, guiding users' attention, and creating a sense of continuity.
Accessibility and Inclusivity: Designing for accessibility ensures that the interface is usable by all
users, including those with disabilities or impairments. Inclusive design principles promote diversity,
equity, and accessibility, aiming to create products that accommodate a wide range of users' needs and
preferences.
Aesthetics and Creativity: Aesthetic design elements, such as colors, typography, and imagery,
contribute to the overall look and feel of the interface. Creativity in design allows for innovative and
engaging solutions that captivate users' attention and evoke positive emotions.
By adhering to user interface design guidelines and principles, designers can create interfaces that are
not only visually appealing but also functional, intuitive, and user-centric. Prioritizing usability,
accessibility, and user experience helps ensure that the interface meets the needs and expectations of
its target audience effectively.
Controls and Components: Controls are UI elements used to interact with an application, such as
buttons, textboxes, checkboxes, and dropdown lists. Components are reusable software units that
encapsulate specific functionality, such as grids, charts, or date pickers. Employing a variety of
controls and components allows users to provide input and interact with the application effectively.
Data Binding and Validation: Data binding is a mechanism for synchronizing data between UI
elements and data sources, such as databases or objects. It allows for automatic updating of UI
elements when underlying data changes. Validation ensures that user input meets certain criteria or
constraints, such as required fields, data types, or ranges. Data binding and validation help maintain
data integrity and improve user experience.
Basic Architecture and Features: GUI applications in C typically follow a layered architecture, with
separate layers for presentation (UI), business logic, and data access. The UI layer contains controls
and components for user interaction, while the business logic layer implements application
functionality. Features such as event handling, navigation, and state management are essential for
responsive and adaptive GUI applications.
Custom Controls and User Controls: Custom controls are specialized UI elements that extend or
customize the functionality of standard controls. User controls are reusable components composed of
multiple controls and logic, encapsulated into a single unit. Custom controls and user controls allow
for modular design and code reuse, facilitating the development of complex GUI applications.
Menus and Toolbars: Menus and toolbars provide users with access to application commands and
functionality. They typically contain options for file operations, editing, formatting, and other
common tasks. Menus and toolbars improve navigation and usability by organizing commands into
logical groups and categories.
Dialogue Boxes: Dialogue boxes, such as message boxes, input boxes, and file dialogs, are used to
interact with users and gather input or provide feedback. They allow users to make choices, enter data,
or respond to prompts. Dialogue boxes enhance user interaction and streamline workflow by guiding
users through tasks and decisions.
13 | P a g e
Scax the one
Providing Input and Output Code Using Standard Practices and Methods:
Standard Input: C provides standard methods for accepting input from users, such as
`[Link]()` for console applications and event handlers for GUI applications. These
methods allow users to input data from the keyboard, mouse, or other input devices.
Standard Output: C also provides standard methods for displaying output to users, such as
`[Link]()` for console applications and updating UI elements for GUI applications. These
methods allow developers to communicate information, results, or feedback to users effectively.
By employing controls effectively, following standard practices for input and output, and
implementing features such as data binding, validation, and custom controls, developers can create
responsive and adaptive GUI applications that meet the needs of users and provide a seamless user
experience.
Define Exception:
An exception is an unexpected or exceptional condition that arises during the execution of a program
and disrupts its normal flow. Exceptions can occur due to various reasons, such as invalid input,
runtime errors, hardware failures, or unexpected conditions in the program's environment. When an
exception occurs, it typically results in the termination of the program's execution unless it is properly
handled.
14 | P a g e
Scax the one
✓ Robustness: Proper exception handling enhances the robustness of a program by gracefully
handling unexpected conditions and preventing abrupt termination.
✓ Error Recovery: Exception handling allows developers to recover from exceptional situations and
continue program execution or take appropriate actions to mitigate the impact of the error.
✓ Debugging: Exception handling provides valuable information about the cause of errors and
facilitates debugging by logging error details, stack traces, and other diagnostic information.
✓ User Experience: Well-designed exception handling improves the user experience by providing
meaningful error messages, guiding users through error scenarios, and preventing application
crashes.
✓ Security: Exception handling helps identify security vulnerabilities and prevents exploitation by
malicious actors by handling errors gracefully and securely.
To create a user-defined exception in C, you can define a custom exception class that inherits from
`[Link]` or one of its subclasses. You can then customize the exception class by adding
properties, constructors, and methods to provide additional information about the error condition.
User-defined exceptions should follow naming conventions and provide meaningful names and
descriptions to convey the nature of the error.
15 | P a g e
Scax the one
2. Catch Blocks: Add one or more `catch` blocks immediately after the `try` block to catch specific
types of exceptions. Each `catch` block specifies the type of exception it handles and provides code to
handle or respond to the exception.
3. Finally Block (Optional): Optionally, add a `finally` block after the `catch` blocks to execute
cleanup or resource release code, regardless of whether an exception occurred.
4. Throw Statement (Optional): Use the `throw` statement to explicitly throw exceptions within the
code, allowing for custom error handling or propagation of exceptions to higher levels.
By following these steps, developers can effectively handle exceptions in C programs, improving
robustness, reliability, and user experience.
16 | P a g e
Scax the one
1. Sequence: Sequence is the simplest programming construct, representing a series of instructions
executed in sequential order. Statements are executed one after another, from top to bottom, without
any branching or repetition. Sequence allows developers to specify the order of operations and define
the flow of execution within a program.
2. Selection (Decision-Making): Selection allows developers to make decisions and choose between
alternative courses of action based on specified conditions. It is typically implemented using
conditional statements, such as `if`, `else if`, and `switch`, which evaluate conditions and execute
different blocks of code accordingly. Selection enables developers to implement branching logic and
handle different scenarios based on runtime conditions.
By understanding and effectively using these programming constructs, developers can write
structured, efficient, and maintainable code to solve a wide range of problems and implement
complex algorithms and logic in their programs.
17 | P a g e
Scax the one
✓ Efficiency: Selection statements help optimize program performance by selectively executing
only the necessary code based on the conditions met. This selective execution reduces
unnecessary computations and improves overall efficiency.
✓ The multiple selection, or `else if` statement, evaluates multiple conditions sequentially and
executes the block of code associated with the first condition that evaluates to true. If none of the
conditions are true, an optional `else` block can be executed.
18 | P a g e
Scax the one
4. Nested Selection:
✓ Nested selection involves embedding one or more selection statements within another selection
statement. This allows for more complex decision-making logic by evaluating conditions
hierarchically.
19 | P a g e
Scax the one
By leveraging these types of selection statements, developers can implement flexible, adaptive, and
efficient logic in their C programs to handle various scenarios and make informed decisions based on
runtime conditions.
do
{
// Code block to execute
20 | P a g e
Scax the one
while (condition);
```
2. While Loop:
- The `while` loop executes a block of code repeatedly while a specified condition is true. It
evaluates the condition before entering the loop body, so the loop may not execute at all if the
condition is false initially.
- Syntax:
```csharp
while (condition)
{
// Code block to execute
}
```
3. For Loop:
- The `for` loop executes a block of code a specified number of times, iterating over a range of
values or elements. It provides a compact syntax for specifying loop initialization, condition, and
iteration expression in a single line.
- Syntax:
```csharp
for (initialization; condition; iteration)
{
// Code block to execute
}
```
- Syntax:
```csharp
foreach (var item in collection)
21 | P a g e
Scax the one
{
// Code block to execute for each item in the collection
}
```
✓ Memory Efficiency: Arrays optimize memory usage by allocating a fixed-size block of memory
to store elements of the same data type. This contiguous allocation minimizes memory
fragmentation and overhead, resulting in efficient memory utilization.
✓ Random Access: Arrays support random access to elements, allowing developers to access any
element in the array directly by its index. This random-access capability enables efficient retrieval
and manipulation of elements based on their position within the array.
✓ Iteration: Arrays facilitate iteration over elements using loop constructs, such as `for` loops or
`foreach` loops. This iteration capability simplifies processing of array elements, enabling
developers to perform operations on each element sequentially.
22 | P a g e
Scax the one
✓ Efficient Data Structures: Arrays serve as the foundation for implementing more complex data
structures, such as lists, stacks, queues, and matrices. These data structures leverage the
underlying array structure to provide additional functionalities and operations.
```
2. Two-Dimensional Array:
✓ A two-dimensional array stores element in rows and columns, forming a grid-like structure. It is
defined by specifying the data type of its elements and the number of rows and columns in square
brackets `[,]`.
Syntax:
```csharp
datatype[,] arrayName = new datatype[rows, columns];
```
3. Jagged Array:
✓ A jagged array is an array of arrays, where each element of the array is itself an array. It allows
for irregular or jagged structures, where the lengths of the individual arrays may vary.
- Syntax:
```csharp
Manipulating Arrays:
✓ Accessing Elements: Elements of an array can be accessed using their indices. The index of the
first element is 0, and the index of the last element is length-1.
✓ Modifying Elements: Elements of an array can be modified by assigning new values to them
using their indices.
23 | P a g e
Scax the one
✓ Adding Elements: Arrays have a fixed size, so elements cannot be added directly. However, new
arrays can be created with larger sizes and existing elements copied over if resizing is necessary.
✓ Removing Elements: Elements cannot be removed directly from an array. However, elements can
be marked as null or replaced with default values to simulate removal.
24 | P a g e
Scax the one
multiple parameters and simplifies function signatures, making code more readable and
maintainable.
```csharp
// Define a structure
public struct Person
{
public string Name;
public int Age;
}
// Instantiate a structure
Person person1 = new Person();
[Link] = "John";
[Link] = 30;
```
25 | P a g e
Scax the one
```csharp
// Access and modify structure members
Modularization, also known as modular programming, is the practice of dividing a program into
separate, self-contained modules or units of functionality. This approach offers several benefits in
programming:
✓ Code Reusability: Modularization promotes code reuse by encapsulating common
functionality into reusable modules. These modules can be used across multiple parts of the
program or in different projects, reducing redundancy and promoting maintainability.
✓ Improved Maintainability: Breaking down a program into modular components makes it
easier to understand, maintain, and update. Each module is focused on a specific task or
functionality, making it easier to locate and modify code when necessary without affecting
other parts of the program.
✓ Enhanced Scalability: Modularization facilitates the addition of new features or
functionalities to a program without disrupting existing code. New modules can be added or
26 | P a g e
Scax the one
existing modules modified independently, allowing the program to scale and evolve over
time.
✓ Simplified Development: Modularization simplifies the development process by breaking
down complex problems into smaller, more manageable components. Developers can focus
on implementing individual modules independently, reducing complexity and improving
productivity.
```csharp
// Define a function
public int Add(int num1, int num2)
{
return num1 + num2;
}
27 | P a g e
Scax the one
```csharp
// Define a function with parameters
}
// Invoke the function with an argument
Greet("John"); // Output: Hello, John!
```
Call by Value: In call by value, a copy of the argument's value is passed to the function, and any
modifications made to the parameter within the function do not affect the original argument. This
method is used for primitive data types, such as integers or floating-point numbers.
Call by Reference: In call by reference, a reference to the argument's memory location is passed to
the function, allowing the function to directly modify the original argument's value. This method is
used for reference types, such as objects or arrays.
28 | P a g e
Scax the one
Define Functions as Methods in Classes:
In C#, functions are typically defined as methods within classes. Methods encapsulate functionality
associated with a class and define the behavior of objects instantiated from the class. Methods can
access and manipulate the data members (fields) of the class and provide an interface for interacting
with objects of the class.
```csharp
public class Calculator
{
// Method to add two numbers
public int Add(int num1, int num2)
{
}
// Method to divide two numbers
public double Divide(double dividend, double divisor)
{
if (divisor != 0)
{
29 | P a g e
Scax the one
{
throw new ArgumentException("Divisor cannot be zero.");
}
}
}
class Program
{
static void Main(string[] args)
{
// Display results
[Link]($"Sum: {sum}");
[Link]($"Difference: {difference}");
[Link]($"Product: {product}");
[Link]($"Quotient: {quotient}");
}
}
```
In this example, the `Calculator` class defines several methods (`Add`, `Subtract`, `Multiply`, and
`Divide`) to perform arithmetic operations. These methods encapsulate the logic for each operation
and can be called from the `Main` method or other parts of the program to perform calculations. By
organizing functionality into methods within classes, developers can achieve code modularity,
encapsulation, and reusability, leading to more maintainable and scalable codebases.
30 | P a g e
Scax the one
LEARNING OUTCOME 7: Manipulate files and databases
in C#
7.1 Handling File Streams:
File Stream:
A file stream is a sequence of bytes flowing between a program and a file on disk. It allows reading
data from files, writing data to files, or performing both read and write operations simultaneously. File
streams provide an abstraction for accessing and manipulating files in a program, enabling
input/output (I/O) operations with files as if they were sequential streams of data.
Output streams, also known as write streams, allow writing data to files. They provide methods for
sequentially writing bytes, characters, or structured data to a file. Output streams are used when the
primary operation is to write data to files, such as creating new files, appending to existing files, or
overwriting file contents.
✓ StreamReader: The `StreamReader` class is used for reading text from a file. It provides
methods for reading characters, lines, or entire files using various encoding options.
`StreamReader` simplifies reading text files by handling character decoding and buffering
internally.
31 | P a g e
Scax the one
✓ StreamWriter: The `StreamWriter` class is used for writing text to a file. It provides methods
for writing characters, strings, or formatted data to a file. `StreamWriter` simplifies writing
text files by handling character encoding and buffering internally.
In C, programs can be written to perform various file operations, including creating, writing, reading,
and appending files, using the `FileStream`, `StreamReader`, and `StreamWriter` classes. Here's an
overview of how to write such programs:
Creating Files: Use the `FileStream` class to create a new file using the `[Link]`
enumeration option.
✓ Writing Files: Use the `StreamWriter` class to write text data to a file. Open the file in write
mode (`[Link]`) and pass the file stream to the `StreamWriter` constructor.
Write data using the `Write` or `WriteLine` methods of the `StreamWriter` class.
✓ Reading Files: Use the `StreamReader` class to read text data from a file. Open the file in
read mode (`[Link]`) and pass the file stream to the `StreamReader` constructor.
Read data using the `Read`, `ReadLine`, or `ReadToEnd` methods of the `StreamReader`
class.
✓ Appending Files: To append data to an existing file, open the file in append mode
(`[Link]`) and use the `StreamWriter` class to write data to the end of the file.
By leveraging these classes and their methods, developers can create versatile programs for file I/O
operations in C, enabling efficient handling of file streams and manipulation of file contents.
32 | P a g e
Scax the one
To create and manage database connections in [Link] using OleDb, you use the
`OleDbConnection` class to establish a connection to the database. You specify the connection string,
which contains information such as the provider, data source, authentication credentials, and other
connection parameters.
```csharp
using [Link];
{
// Open the connection
[Link]();
```csharp
using [Link];
// Create a DataSet
DataSet = new DataSet();
33 | P a g e
Scax the one
// Create an OleDbDataAdapter to populate the DataSet
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT FROM MyTable", connection);
[Link](dataSet, "MyTable");
}
```
Explain the Process of Retrieving Data from the Database:
The process of retrieving data from a database using OleDb is similar to other database providers.
You establish a connection to the database, execute a query using a command object
(`OleDbCommand`), and then process the results using a data reader (`OleDbDataReader`) or fill a
dataset (`DataSet`) using a data adapter (`OleDbDataAdapter`).
// Create a DataGridView
DataGridView dataGridView = new DataGridView();
[Link] = [Link]["MyTable"];
```
34 | P a g e
Scax the one
`DeleteCommand` properties to automatically generate SQL commands based on changes in the
dataset.
```csharp
using [Link];
select item;
The End
But wonera
35 | P a g e
Scax the one