Project Work Questions of C#
1. Explain the .NET architecture.
Ans: The .NET architecture is a framework developed by Microsoft that provides a platform for
building and running various applications. Here's a breakdown of its key components:
Core Components:
Common Language Runtime (CLR):
o This is the heart of the .NET architecture. It's the execution engine that manages
running .NET applications.
o Key responsibilities include:
Memory management (garbage collection).
Exception handling.
Security.
Type safety.
Just-In-Time (JIT) compilation, which converts intermediate language code
into machine code for the specific platform.
.NET Class Library:
o This is a vast collection of pre-written code (classes and APIs) that developers can use
to build applications.
o It provides functionality for common tasks like:
Working with data (databases, files).
Building user interfaces (web, desktop, mobile).
Networking.
Cryptography.
Common Language Infrastructure (CLI):
o This is an open specification that describes the executable code and runtime
environment that forms the basis of .NET.
o It enables interoperability between different programming languages that target
the .NET platform.
Programming Languages:
o .NET supports multiple programming languages, including:
C#
Visual Basic (.NET)
F#
o These languages compile to Common Intermediate Language (CIL), which the CLR
then executes.
Key Architectural Concepts:
Managed Code:
o Code written for the .NET framework is "managed," meaning the CLR handles
memory management and other tasks.
o This helps prevent common programming errors and improves security.
Cross-Platform Capabilities:
o Modern .NET (.NET Core and .NET 5+) is designed to be cross-platform, allowing
applications to run on Windows, Linux, and macOS.
Language Interoperability:
o Because .NET languages compile to CIL, they can easily interoperate, allowing
developers to use different languages within the same application.
In essence:
1
The .NET architecture provides a standardized environment for developing and running
applications.
The CLR manages the execution of code, while the class library provides a rich set of tools
and functionalities.
.Net has evolved to be a very versatile platform, that allows for many different types of
application development.
I hope this helps!
2. Compare and contrast .NET Framework, .NET Core and .NET standard. In what scenarios
would you select each one?
Ans: the differences and similarities between .NET Framework, .NET Core, and .NET Standard,
and explore when to use each.
.NET Framework
Description:
o The original .NET implementation.
o Primarily designed for Windows-based applications.
o Includes a comprehensive set of libraries and APIs.
o Tightly coupled with the Windows operating system.
Key Features:
o Windows Forms and WPF for desktop application development.
o ASP.NET for web application development.
o WCF (Windows Communication Foundation) for service-oriented applications.
o A vast ecosystem of third-party libraries.
Limitations:
o Windows-only.
o Larger installation footprint.
o Slower release cycle compared to .NET Core/.NET
.NET Core/.NET (.NET 6 and later)
Description:
o A cross-platform, open-source implementation of .NET.
o Designed for modern, cloud-based applications.
o Highly modular and optimized for performance.
o ".NET Core" has evolved into ".NET" starting with version 6. Meaning that ".NET" is
now the current implementation of cross platform .Net.
Key Features:
o Cross-platform support (Windows, Linux, macOS).
o High performance.
o Modular architecture.
o Support for containers and microservices.
o ASP.NET Core for modern web applications.
Advantages:
o Cross-platform capabilities.
o Improved performance.
o Smaller installation footprint.
o Faster release cycle.
.NET Standard
Description:
o A formal specification of .NET APIs intended to be implemented by .NET
implementations.
2
o Its goal was to unify the .NET ecosystem, enabling code sharing across .NET
Framework, .NET Core, and Xamarin.
o Helped developers to build libraries that could run on multiple .NET implementations.
Important change:
o .NET Standard is becoming less relevant with newer .NET versions (.NET 6+).
Microsoft now recommends targeting .NET 6 (or later) directly for cross-platform
compatibility.
Comparison Table
Feature .NET .NET (.NET .NET Standard
Framework Core)
Platform Windows Only Cross-Platform Specification
Use Case Windows Cloud, Web, Library cross
desktop, older modern apps, compatability. (less
Web apps cross-platform relevant now)
Open Partially Yes Specification
Source
Performance Good Excellent N/A
Modernity Older Modern Older standard,
superceeded by just
using .Net newest
versions.
Scenario Selection
.NET Framework:
o You have a large, existing Windows Forms or WPF application that requires minimal
changes.
o You are working on a project with strict dependencies on Windows-specific libraries
that are not available in .NET.
o you have existing older web forms applications.
.NET (.NET Core):
o You are building new web applications, microservices, or cloud-based applications.
o You need cross-platform support (Windows, Linux, macOS).
o You prioritize performance and a smaller deployment footprint.
o you are creating any modern .net application.
.NET Standard:
o Historically, this was used when you needed to create libraries that could run on
multiple .NET implementations. However, with modern .Net, target the desired .Net
version directly.
In summary:
.NET is the future of .NET development.
.NET Framework is for legacy Windows applications.
.Net Standard is mostly replaced by targeting the desired .Net version directly.
I hope this helps!
3. Define CLR. Explain how CLR works.
Ans: The Common Language Runtime (CLR) is a fundamental component of Microsoft's .NET
Framework. Essentially, it's the virtual machine that manages the execution of .NET programs.
Definition:
The CLR provides a runtime environment that handles the execution of code written in
various .NET programming languages, such as C#, VB.NET, and F#.
3
It's responsible for services like memory management, type safety, security, and exception
handling.
How the CLR Works:
Here's a simplified explanation of the CLR's operation:
1. Compilation to Intermediate Language (IL):
o When you compile a .NET program, the source code is not directly translated into
machine code. Instead, it's compiled into an intermediate language called Common
Intermediate Language (CIL), also sometimes referred to as MSIL (Microsoft
Intermediate Language).
o This IL code is platform-independent.
2. Just-In-Time (JIT) Compilation:
o When the .NET program is executed, the CLR's Just-In-Time (JIT) compiler takes
over.
o The JIT compiler converts the IL code into native machine code that's specific to the
underlying hardware and operating system.
o This compilation occurs during runtime, hence the name "Just-In-Time."
3. Runtime Services:
o The CLR provides various runtime services that are crucial for the execution of .NET
applications:
Memory Management (Garbage Collection): The CLR automatically manages
memory allocation and deallocation through a process called garbage
collection. This helps prevent memory leaks and other memory-related issues.
Type Safety: The CLR enforces type safety, ensuring that data types are used
correctly and preventing type-related errors.
Security: The CLR provides security features that protect the system from
malicious code.
Exception Handling: The CLR provides a structured mechanism for handling
runtime errors (exceptions).
Cross-Language Interoperability: The CLR enables code written in
different .NET languages to interact seamlessly. This is achieved through the
Common Type System (CTS).
In essence, the CLR acts as a layer between your .NET code and the operating system, providing
a managed execution environment that enhances reliability, security, and portability.
4. Define constructor and destructor with examples.
Ans: Certainly, let's define constructors and destructors in C# with examples.
Constructors (C#):
Definition:
o In C#, a constructor is a special method that is called when an instance of a class is
created.
o Its primary role is to initialize the object's fields and perform any necessary setup.
o Constructors have the same name as the class.
o They do not have a return type (not even void).
o C# supports constructor overloading, allowing multiple constructors with different
parameters.
Purpose:
o To ensure that objects are created in a valid state.
o To initialize member variables.
o To perform any setup tasks required when an object is created.
Example (C#):
4
C#
using System;
public class MyClass
{
public int value;
// Default constructor
public MyClass()
{
value = 0;
Console.WriteLine("Default constructor called.");
}
// Parameterized constructor
public MyClass(int val)
{
value = val;
Console.WriteLine($"Parameterized constructor called, value: {value}");
}
}
public class Program
{
public static void Main(string[] args)
{
MyClass obj1 = new MyClass(); // Calls the default constructor
MyClass obj2 = new MyClass(10); // Calls the parameterized constructor
}
}
Destructors (C#) / Finalizers:
Definition:
o In C#, destructors are called finalizers.
o A finalizer is a special method that is called by the garbage collector when an object is
about to be reclaimed.
o It is used to release unmanaged resources held by the object.
o Finalizers are declared using a tilde (~) followed by the class name.
o C# programmers rarely implement finalizers directly. The using statement and
IDisposable interface are preferred for resource management.
Purpose:
o To release unmanaged resources (e.g., file handles, database connections, unmanaged
memory).
o To perform cleanup operations before an object is garbage collected.
o It is important to note that the garbage collector is non deterministic, so you cannot
know exactly when a finalizer will be called.
Example (C#):
C#
using System;
public class MyClass
5
{
// ... (other members)
// Finalizer
~MyClass()
{
Console.WriteLine($"Finalizer called, value: {value}");
// Release unmanaged resources here
}
public MyClass(int val)
{
value = val;
}
}
public class Program
{
public static void Main(string[] args)
{
MyClass obj = new MyClass(30);
// ... (some code)
// the garbage collector will eventually call the finalizer.
}
}
Important considerations regarding finalizers:
Finalizers should only be used to release unmanaged resources.
Avoid performing lengthy or blocking operations in finalizers, as they can delay garbage
collection.
For managed resources, use the using statement or implement the IDisposable interface.
Finalizers are non deterministic, and therefore should not be relied upon for critical
operations that must be performed at a specific time.
The garbage collector handles managed resources automatically.
In C#, the IDisposable interface and the using statement are the preferred mechanisms for
deterministic resource management, which is often more desirable than relying on finalizers.
5. Define inheritance and its types.
Ans:In C#, inheritance is a fundamental concept of object-oriented programming (OOP) that
allows you to create a new class (derived class or child class) based on an existing class (base
class or parent class). The derived class inherits the1 members (fields, properties, methods, etc.)
of the base class, promoting code reusability and establishing an "is-a" relationship between the
classes.
Here's a breakdown:
What is Inheritance?
Code Reusability:
o Inheritance enables you to reuse code from an existing class, reducing redundancy and
improving maintainability.
"Is-a" Relationship:
o It models the "is-a" relationship, where a derived class is a specialized version of the
base class. For example, a "Car" is-a "Vehicle."
6
Extensibility:
o Derived classes can extend or modify the behavior of the base class, allowing you to
customize functionality.
Types of Inheritance in C#:
C# supports the following types of inheritance:
Single Inheritance:
o A derived class inherits from only one base class. This is the most common and
straightforward type of inheritance.
o Example:
class Animal { ... }
class Dog : Animal { ... }
Multilevel Inheritance:
o A derived class inherits from another derived class, forming a chain of inheritance.
o Example:
class Animal { ... }
class Mammal : Animal { ... }
class Dog : Mammal { ... }
Hierarchical Inheritance:
o Multiple derived classes inherit from a single base class.
o Example:
class Animal { ... }
class Dog : Animal { ... }
class Cat : Animal { ... }
Multiple Inheritance (Interface-Based):
o C# does not directly support multiple inheritance of classes (a class inheriting from
multiple base classes). However, it achieves a form of multiple inheritance through
interfaces.
2
o A class can implement multiple interfaces, allowing it to inherit the contracts (method
signatures) defined by those interfaces.
o Example:
interface IDrawable { void Draw(); }
interface IMovable { void Move(); }
class Shape : IDrawable, IMovable { ... }
Key Points:
Inheritance promotes code organization and maintainability.
It's essential to use inheritance appropriately, favoring composition when necessary.
C# enforces single class inheritance, but allows for the implementation of multiple interfaces.
6. What are the access modifiers allowed in C#?
Ans:In C#, access modifiers control the visibility of types and type members. Here's a
breakdown of the commonly used access modifiers:
public:
o Accessible from anywhere.
o This is the most permissive access level.
private:
o Accessible only within the same class or struct.
o This is the most restrictive access level.
protected:
o Accessible within the same class or struct, and in derived classes.
o Used to allow derived classes to access base class members.
7
internal:
o Accessible within the same assembly.
o An assembly is a compiled code library (.dll or .exe).
protected internal:
o Accessible within the same assembly, or from derived classes in another assembly.
o A combination of protected and internal.
private protected:
o Accessible within the containing class, or within derived classes that are within the
same assembly.
file:
o This access modifier restricts the visibility of a top-level type to the source file in
which it is declared.
o This is a relatively new access modifier, introduced in C# 11.
Key points to remember:
Access modifiers are essential for encapsulation, which is a fundamental principle of object-
oriented programming.
They help to control the scope of your code and prevent unintended access to sensitive data.
The default access level will change depending on the context of the code.
7. Define polymorphism. What are the differences between function overloading and overriding?
Explain with examples.
Ans: Certainly! Let's break down polymorphism and the differences between function
overloading and overriding in C#.
1. Definition of Polymorphism
Polymorphism is a fundamental concept in object-oriented programming (OOP) that allows
objects of different types to be treated as objects of1 a common type. In essence, it means
"many forms." It enables a single interface to represent different underlying forms (data types
or classes).
In C#, polymorphism is achieved through two main mechanisms:
o Compile-time polymorphism (static polymorphism): Achieved through method
overloading.
o Run-time polymorphism (dynamic polymorphism): Achieved through method
overriding.
2. Function Overloading vs. Overriding
Here's a breakdown of the key differences:
Function Overloading:
o Occurs within the same class.
o Involves methods with the same name but different parameter lists (different number,
types, or order of parameters).
o The compiler determines which method to call at compile time (compile-time
polymorphism).
o Increases code readability by allowing you to use the same method name for similar
operations with different inputs.
Function Overriding:
o Occurs between a base class and a derived class.
o Involves a derived class providing a specific implementation for a method that is
already defined in the base class.
o The base class method must be declared as virtual, and the derived class method must
be declared as override.
8
o The runtime determines which method to call based on the actual object type (run-
time polymorphism).
o Enables you to customize or extend the behavior of inherited methods.
3. C# Examples
Here are C# examples to illustrate overloading and overriding:
Function Overloading Example:
C#
public class Calculator
{
public int Add(int a, int b)
{
return a + b;
}
public double Add(double a, double b)
{
return a + b;
}
public int Add(int a, int b, int c)
{
return a + b + c;
}
}
public class ExampleOverloading
{
public static void Main(string[] args)
{
Calculator calc = new Calculator();
Console.WriteLine(calc.Add(2, 3)); // Calls Add(int, int)
Console.WriteLine(calc.Add(2.5, 3.5)); // Calls Add(double, double)
Console.WriteLine(calc.Add(1, 2, 3)); // Calls Add(int, int, int)
}
}
Function Overriding Example:
C#
public class Animal
{
public virtual void MakeSound()
{
Console.WriteLine("Animal makes a sound");
}
}
public class Dog : Animal
{
public override void MakeSound()
{
Console.WriteLine("Dog barks");
9
}
}
public class Cat : Animal
{
public override void MakeSound()
{
Console.WriteLine("Cat meows");
}
}
public class ExampleOverriding
{
public static void Main(string[] args)
{
Animal animal1 = new Animal();
Animal animal2 = new Dog();
Animal animal3 = new Cat();
animal1.MakeSound(); // Animal makes a sound
animal2.MakeSound(); // Dog barks
animal3.MakeSound(); // Cat meows
}
}
In the overriding example, even though animal2 and animal3 are declared as Animal, the
specific MakeSound() method that is executed depends on the actual object type at runtime (Dog
or Cat). This demonstrates run-time polymorphism.
8. Explain interfaces and write a C# program for extending and combining interfaces.
Ans:Certainly! Let's break down interfaces and how to work with them in C#.
What are Interfaces?
In C#, an interface is a contract that defines a set of methods, properties, events, and indexers
that a class or struct must implement. It's like a blueprint that specifies what a class should do,
but not how it should do it.
Key Characteristics:
Contracts: Interfaces define a contract that implementing classes must adhere to.
Abstraction: They provide a way to achieve abstraction, separating the "what" from the
"how."
Multiple Inheritance (of behavior): C# doesn't support multiple inheritance of classes, but a
class can implement multiple interfaces, allowing it to exhibit multiple behaviors.
No Implementation Details (prior to C# 8.0): Before C# 8.0, interfaces could only contain
method signatures, not implementations. However, C# 8.0 introduced default interface
methods, allowing interfaces to provide default implementations.
Extending and Combining Interfaces
Interfaces can inherit from other interfaces, creating more specialized contracts. This is how you
extend and combine them.
C# Code Example:
C#
using System;
10
// Basic interfaces
interface IDrawable
{
void Draw();
}
interface IResizable
{
void Resize(int width, int height);
}
// Extended interface (combining)
interface IDrawableResizable : IDrawable, IResizable
{
// Additional methods, if needed
}
// Implementing class
class Rectangle : IDrawableResizable
{
private int width;
private int height;
public Rectangle(int width, int height)
{
this.width = width;
this.height = height;
}
public void Draw()
{
Console.WriteLine($"Drawing rectangle: Width={width}, Height={height}");
}
public void Resize(int newWidth, int newHeight)
{
width = newWidth;
height = newHeight;
Console.WriteLine($"Resizing rectangle: Width={width}, Height={height}");
}
}
class Program
{
static void Main(string[] args)
{
Rectangle rect = new Rectangle(10, 5);
rect.Draw();
rect.Resize(20, 10);
11
rect.Draw();
//using interface references.
IDrawable drawRef = rect;
IResizable resizeRef = rect;
IDrawableResizable bothRef = rect;
drawRef.Draw();
resizeRef.Resize(5,5);
bothRef.Draw();
}
}
Explanation:
1. Basic Interfaces (IDrawable, IResizable):
o These define simple contracts: IDrawable for drawing and IResizable for resizing.
2. Extended Interface (IDrawableResizable):
o This interface inherits from both IDrawable and IResizable, combining their contracts.
o Any class that implements IDrawableResizable must provide implementations for all
methods defined in both base interfaces.
3. Implementing Class (Rectangle):
o The Rectangle class implements IDrawableResizable, so it must provide
implementations for Draw() and Resize().
4. Main Method:
o demonstrates creating a rectangle object, and calling methods from the interface.
o Also shows how interface references can be used to call the methods, and how an
object can be referenced by multiple interfaces.
Key Benefits of Interfaces:
Loose Coupling: Interfaces allow you to write code that depends on abstractions rather than
concrete implementations, making your code more flexible and maintainable.
Polymorphism: You can use interface references to work with objects of different classes that
implement the same interface.
Code Reusability: Interfaces promote code reusability by defining common behaviors that
can be implemented by multiple classes.
9. What are partial classes, static classes and sealed classes in C#? Provide examples of each.
Ans:In C#, partial, static, and sealed classes serve distinct purposes, enhancing code
organization, utility, and security. Here's a breakdown of each:
1. Partial Classes:
Definition:
o Partial classes allow the definition of a single class to be split across multiple files.
This is particularly useful for large projects or when working with auto-generated
code.
o The partial keyword is used to indicate that a class is split.
Use Cases:
o Organizing large classes into smaller, more manageable files.
o Separating auto-generated code from developer-written code.
o Enabling multiple developers to work on different parts of a class simultaneously.
Example:
C#
12
// File1.cs
public partial class Employee
{
public void DisplayName()
{
Console.WriteLine("Employee Name: John Doe");
}
}
// File2.cs
public partial class Employee
{
public void DisplayID()
{
Console.WriteLine("Employee ID: 12345");
}
}
//Program.cs
public class Program
{
public static void Main(string[] args)
{
Employee emp = new Employee();
emp.DisplayName();
emp.DisplayID();
}
}
2. Static Classes:
Definition:
o Static classes cannot be instantiated. They contain only static members (fields,
methods, properties).
o They are used to group related utility functions.
Use Cases:
o Creating utility libraries.
o Providing global access to functions and data.
o Encapsulating logic that doesn't require instance-specific data.
Example:
C#
public static class MathUtils
{
public static int Add(int a, int b)
{
return a + b;
}
}
public class Program
{
public static void Main(string[] args)
13
{
int sum = MathUtils.Add(5, 3);
Console.WriteLine($"Sum: {sum}");
}
}
3. Sealed Classes:
Definition:
o Sealed classes cannot be inherited. This prevents other classes from deriving from
them.
o They are used to restrict inheritance and ensure the integrity of a class.
Use Cases:
o Preventing unintended inheritance.
o Securing sensitive classes.
o Optimizing performance, as the compiler can make certain assumptions about sealed
classes.
Example:
C#
public sealed class FinalClass
{
public void DisplayMessage()
{
Console.WriteLine("This is a sealed class.");
}
}
public class Program
{
public static void Main(string[] args)
{
FinalClass final = new FinalClass();
final.DisplayMessage();
}
}
//attempting to inherit from FinalClass would result in a compiler error.
In summary, partial classes aid in code organization, static classes provide utility functionality,
and sealed classes control inheritance.
10. Explain lambda expression and its implementation.
Ans: Lambda expressions in C# provide a concise way to write anonymous functions. Here's a
breakdown of what they are and how they're implemented:
What are Lambda Expressions?
Anonymous Functions:
o Lambda expressions are essentially anonymous functions, meaning they are functions
without a name.
o They allow you to write inline code that can be passed as a delegate or expression
tree.
Concise Syntax:
o They offer a more compact syntax compared to traditional anonymous methods.
o This makes code more readable, especially when dealing with short, simple functions.
Delegate and Expression Tree Compatibility:
14
o Lambda expressions can be used to create delegates, which are type-safe function
pointers.
o They can also be used to create expression trees, which represent code as data
structures, enabling powerful querying and manipulation.
Implementation in C#
Lambda Operator (=>):
o The core of a lambda expression is the lambda operator =>, which separates the input
parameters from the lambda body.
Syntax:
o (input-parameters) => expression (Expression lambda)
o (input-parameters) => { <sequence-of-statements> } (Statement lambda)
Types of Lambda Expressions:
o Expression Lambdas:
These have a single expression as their body.
The result of the expression is returned.
Example: x => x * 2 (doubles the input value).
o Statement Lambdas:
These have a block of statements enclosed in curly braces {} as their body.
They can contain multiple statements and perform more complex operations.
Example: x => { Console.WriteLine(x); return x * 2; } (prints the input and
doubles it).
Usage:
o Delegates:
Lambda expressions are commonly used with delegates like Func and Action.
Func delegates represent functions that return a value.
Action delegates represent functions that don't return a value.
o LINQ (Language Integrated Query):
Lambda expressions are heavily used in LINQ for querying and manipulating
data collections.
They provide a concise way to define filtering, sorting, and other operations.
Example:
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class LambdaExample
{
public static void Main(string[] args)
{
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Using a lambda expression with LINQ's Where method
var evenNumbers = numbers.Where(x => x % 2 == 0);
Console.WriteLine("Even numbers:");
foreach (var number in evenNumbers)
{
Console.WriteLine(number);
}
15
//using a Func delegate.
Func<int, int> square = x => x * x;
Console.WriteLine(square(5));
//using an Action delegate.
Action<string> greet = name => {
Console.WriteLine($"Hello, {name}!");
};
greet("World");
}
}
In this example:
x => x % 2 == 0 is a lambda expression that filters even numbers.
x => x * x is a lambda expression that squares a number.
name => { Console.WriteLine($"Hello, {name}!"); } is a lambda expression that prints a
greeting.
Lambda expressions enhance code readability and provide a powerful way to work with
functions in C#.
11. What are the advantages of using String Builder class over String class? Give examples.
Ans: In C#, the String and StringBuilder classes both handle text, but they do so with crucial
differences that impact performance. Here's a breakdown of their advantages and when to use
them:
String Class:
Immutability:
o String objects are immutable, meaning their values cannot be changed after creation.
Any operation that appears to modify a string actually creates a new string1 object.
o This immutability provides thread safety and makes strings predictable.
Advantages:
o Simplicity: Strings are easy to use for simple operations.
o Thread safety: Immutability makes them inherently thread-safe.
o String interning: The .NET runtime can optimize string storage by sharing identical
string literals.
Disadvantages:
o Performance overhead: Frequent string modifications, especially in loops, can lead to
excessive memory allocation and garbage collection, impacting performance.
StringBuilder Class:
Mutability:
o StringBuilder objects are mutable, allowing you to modify their contents without
creating new objects.
o This makes them efficient for dynamic string manipulation.
Advantages:
o Performance: StringBuilder is significantly faster for operations involving frequent
string modifications, such as concatenation in loops.
o Memory efficiency: It reduces memory overhead by modifying the existing object
instead of creating new ones.
Disadvantages:
16
o Slightly more complex syntax.
o Not inherently thread-safe. If multiple threads will be editing the same StringBuilder,
you must implement your own thread safety.
When to Use Which:
Use String when:
o You're working with small, fixed strings.
o You don't need to modify strings frequently.
o Thread safety is a primary concern.
Use StringBuilder when:
o You need to perform frequent string modifications, such as concatenation in loops.
o You're building large strings dynamically.
o Performance is critical.
Examples:
String (inefficient for repeated concatenation):
C#
string result = "";
for (int i = 0; i < 10000; i++)
{
result += i.ToString(); // Creates a new string each time
}
Console.WriteLine(result);
StringBuilder (efficient for repeated concatenation):
C#
System.Text.StringBuilder sb = new System.Text.StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append(i.ToString()); // Modifies the existing StringBuilder
}
string result = sb.ToString();
Console.WriteLine(result);
In the second example, the StringBuilder avoids creating numerous intermediate string objects,
resulting in significantly better performance, especially for large numbers of concatenations.
12. Compare and contrast generic and non-generic collections in C#.
Ans: In C#, collections are used to store and manage groups of objects. They are broadly
categorized into generic and non-generic collections, each with distinct characteristics. Here's a
comparison:
Non-Generic Collections (System.Collections)
Type Safety:
o Non-generic collections store elements as object types.
o This means they can hold any data type, but it also means there's no compile-time type
checking.
o You often need to perform explicit casting when retrieving elements, which can lead
to runtime InvalidCastException errors.
Performance:
o When working with value types (like int, double, etc.), non-generic collections
involve boxing (converting value types to reference types) and unboxing (converting
reference types back to value types).
o These boxing and unboxing operations introduce performance overhead.
Usability:
17
o Because of the need for casting, non-generic collections can make code less readable
and more error-prone.
o Examples: ArrayList, Hashtable, Queue, Stack.
Generic Collections (System.Collections.Generic)
Type Safety:
o Generic collections are strongly typed. You specify the type of elements the collection
will hold when you declare it (e.g., List<int>, Dictionary<string, object>).
o This provides compile-time type checking, preventing many runtime type errors.
Performance:
o Generic collections avoid the overhead of boxing and unboxing for value types,
resulting in better performance.
o They generally offer better performance than non-generic collections, especially when
dealing with value types.
Usability:
o Generic collections are more user-friendly because they eliminate the need for explicit
casting when retrieving elements.
o This makes code more readable and less error-prone.
o Examples: List<T>, Dictionary<TKey, TValue>, Queue<T>, Stack<T>, HashSet<T>.
Key Differences Summarized:
Type Safety: Generics are type-safe; non-generics are not.
Performance: Generics are generally more performant due to the absence of
boxing/unboxing.
Usability: Generics are more user-friendly due to the elimination of explicit casting.
In modern C# development:
Generic collections are strongly preferred due to their superior type safety and performance.
Non-generic collections are primarily used in legacy code or in situations where
interoperability with older systems is required.
In essence, generic collections provide a more robust, efficient, and developer-friendly way to
work with collections in C#.
13. How events are handled through delegates? Explain with examples.
Ans: In C#, delegates and events work together to provide a powerful mechanism for event
handling. Here's a breakdown of how they function, along with illustrative examples:
Delegates: Function Pointers
Definition:
o A delegate is essentially a type-safe function pointer. It holds a reference to a method.
o Delegates define a signature (return type and parameters), and any method that
matches that signature can be assigned to the delegate.
Purpose:
o They enable you to pass methods as arguments to other methods.
o They facilitate the implementation of callback mechanisms.
Events: Secure Notifications
Definition:
o Events are a special type of delegate that provides a controlled way for objects to
notify other objects when something happens.
o They encapsulate delegates, restricting how they can be invoked.
Purpose:
o They implement the observer pattern, where objects (subscribers) can register to
receive notifications from another object (publisher).
o They ensure that only the class that declares the event can raise it.
18
How They Work Together
1. Delegate Declaration:
o You define a delegate that specifies the signature of the methods that can handle the
event.
2. Event Declaration:
o You declare an event based on the delegate type.
3. Event Subscription:
o Subscribers add their methods to the event's invocation list using the += operator.
4. Event Raising:
o The publisher raises the event, which invokes all the subscribed methods.
Example
C#
using System;
// 1. Define a delegate
public delegate void MyEventHandler(string message);
public class EventPublisher
{
// 2. Declare an event
public event MyEventHandler MyEvent;
public void DoSomething()
{
Console.WriteLine("Publisher doing something...");
// 3. Raise the event
if (MyEvent != null)
{
MyEvent("Event occurred!");
}
}
}
public class EventSubscriber
{
public void HandleEvent(string message)
{
Console.WriteLine($"Subscriber received: {message}");
}
}
public class Program
{
public static void Main(string[] args)
{
EventPublisher publisher = new EventPublisher();
EventSubscriber subscriber = new EventSubscriber();
// 4. Subscribe to the event
publisher.MyEvent += subscriber.HandleEvent;
19
publisher.DoSomething();
}
}
Explanation:
MyEventHandler is a delegate that can hold references to methods that take a string
parameter.
MyEvent is the event of the EventPublisher class, and it is based on the MyEventHandler
delegate.
The EventSubscriber class has a method HandleEvent that matches the MyEventHandler
delegate's signature.
In Main, the subscriber.HandleEvent method is added to the publisher.MyEvent event.
When publisher.DoSomething() is called, it raises the MyEvent, which in turn calls the
subscriber.HandleEvent method.
Key Points:
Events provide a way to decouple objects, allowing them to communicate without tight
dependencies.
Delegates and events are fundamental to building flexible and extensible applications in C#.
The "?." operator that is used when invoking events, is called the null conditional operator.
This is used to ensure that if there are no subscribers to an event, that the program does not
throw a null reference exception.
14. With diagrams, explain the working of data access models in ADO.NET.
Ans: ADO.NET in C# offers two primary data access models: connected (DataReader) and
disconnected (DataSet), each with different strengths and weaknesses for managing data access
and manipulation. The connected model maintains a persistent connection to the database, while
the disconnected model fetches data into memory and allows for offline manipulation before
updating the database.
1. Connected Data Access (DataReader):
Concept: This model establishes a connection to the database, executes a query, and reads
the results directly using a SqlDataReader (or similar for other database providers).
Diagram:
Application --(Connection)--> Database
|
| (SQL Command)
V
| (Result Set)
V
SqlDataReader
Advantages:
Efficient for Streaming Data: Ideal for scenarios where you need to process data as
it is retrieved, without storing it in memory.
Resource Management: Connection is closed automatically after the data is read.
Disadvantages:
Requires Constant Connection: The database connection must remain open while
you are working with the data, which can be resource-intensive.
Not Suitable for Offline Manipulation: You cannot perform operations on the data
outside the database connection.
2. Disconnected Data Access (DataSet):
20
Concept: This model establishes a connection to the database, retrieves data into
a DataSet object (which contains one or more DataTable objects), and then allows you to
work with the data in memory, offline.
Diagram:
Application --(Connection)--> Database
|
| (SQL Command)
V
| (Result Set)
V
DataAdapter --(Fill)--> DataSet
Advantages:
Offline Manipulation: You can perform operations on the data in memory, even
without a database connection.
Batch Updates: You can make multiple changes to the data in the DataSet and then
update the database in a single transaction.
Data Binding: DataSet objects are well-suited for binding data to UI controls in
applications.
Disadvantages:
Resource Intensive: Storing large datasets in memory can consume significant
resources.
Synchronization Issues: Changes made in the DataSet need to be synchronized with
the database, which can introduce complexity.
Key ADO.NET Components:
SqlConnection (or similar): Establishes a connection to the database.
SqlCommand (or similar): Represents a SQL command to be executed against the database.
SqlDataReader (or similar): Reads the data returned by a SQL command in a connected
model.
SqlDataAdapter (or similar): Fetches data from the database and populates a DataSet in a
disconnected model.
DataSet: An in-memory representation of a database, containing one or
more DataTable objects.
DataTable: Represents a single table of data within a DataSet
15. Write the steps required for establishing database connectivity using ADO.NET.
Ans: C# using System.Data.SqlClient; // For SQL Server
// Or use System.Data.OleDb for other data sources like MS Access
// 1. Include the necessary namespace:
// As shown above, include the appropriate namespace for your database provider.
// 2. Create a Connection String:
// This string contains the information needed to connect to the database.
string connectionString = "Data Source=YourServerName;Initial
Catalog=YourDatabaseName;User ID=YourUsername;Password=YourPassword;";
// For SQL Server Express using Windows Authentication:
21
// string connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial
Catalog=YourDatabaseName;Integrated Security=True;";
//For MS Access:
// string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Path\\To\\
Your\\Database.accdb;Persist Security Info=False;";
// 3. Create a Connection Object:
// Instantiate a connection object using the connection string.
SqlConnection connection = new SqlConnection(connectionString);
// Or OleDbConnection for other Data Sources.
// OleDbConnection connection = new OleDbConnection(connectionString);
// 4. Open the Connection:
// Open the connection to the database.
try
{
connection.Open();
// 5. Create a Command Object (Optional):
// If you need to execute SQL commands, create a command object.
string sql = "SELECT * FROM YourTableName";
SqlCommand command = new SqlCommand(sql, connection);
// Or OleDbCommand for other Data Sources.
// OleDbCommand command = new OleDbCommand(sql, connection);
// 6. Execute the Command (Optional):
// Execute the SQL command and retrieve data (if applicable).
SqlDataReader reader = command.ExecuteReader();
// Or OleDbDataReader for other Data Sources.
// OleDbDataReader reader = command.ExecuteReader();
// 7. Process the Results (Optional):
// Read and process the data returned by the query.
while (reader.Read())
{
// Access data using reader["ColumnName"] or reader[columnIndex]
Console.WriteLine(reader["ColumnName"]); // Example
}
// 8. Close the Reader (Optional):
// Close the data reader when finished.
if(reader != null && !reader.IsClosed)
{
reader.Close();
}
}
catch (Exception ex)
{
22
Console.WriteLine("Error: " + ex.Message);
}
finally
{
// 9. Close the Connection:
// Close the connection to the database (important!).
if (connection != null && connection.State == System.Data.ConnectionState.Open)
{
connection.Close();
}
}
Key improvements and explanations:
Clearer Connection String Examples: Provides specific connection string examples for SQL
Server (including SQL Server Express with Windows Authentication) and MS Access,
covering common scenarios.
try-catch-finally Block: Implements a try-catch-finally block for robust error handling and
resource management. The finally block ensures the connection is closed even if an
exception occurs.
Reader Closing: Explicitly closes the SqlDataReader (or OleDbDataReader) after use,
preventing resource leaks.
Command Object Explanation: Clearly explains the purpose of the SqlCommand (or
OleDbCommand) object and its use in executing SQL commands.
Data Processing Example: Includes a basic example of how to read and process data from the
SqlDataReader.
Namespace Clarity: Emphasizes the importance of including the correct namespace for the
database provider (System.Data.SqlClient or System.Data.OleDb).
Resource Management: The revised code correctly implements resource management,
especially the closing of the connection and reader, even when errors occur.
Generalization: The code now supports both SQL Server and other data sources such as MS
Access, by using the correct namespaces and connection objects.
Null and State Checks: Added checks to ensure the reader and connection are not null and are
in the open state before attempting to close them. This prevents potential
NullReferenceException and InvalidOperationException issues.
16. What is LINQ? How LINQ is used? Explain with example.
Ans: LINQ, or Language Integrated Query, is a powerful feature in the .NET framework that
allows developers to write queries directly within C# or Visual Basic code to retrieve and
manipulate data from various sources.1 Here's a breakdown:
What is LINQ?
Integration:
2
o LINQ integrates query capabilities directly into the programming language. This
means you can use a consistent syntax to query different data sources.3
Data Sources:
o It works with various data sources, including:
4
Collections (arrays, lists)
5
Databases (SQL)
6
XML documents
And more.
Benefits:
23
o Readability: LINQ queries are often more concise and easier to read than traditional
loop-based approaches.7
o Type Safety: LINQ is strongly typed, providing compile-time checking and
IntelliSense support.8
9
o Consistency: It provides a uniform syntax for querying different data sources.
How LINQ is Used:
LINQ uses a set of standard query operators to perform operations like:
10
Filtering (where)
11
Sorting (orderby)
12
Grouping (groupby)
Selecting (select)
13
Joining (join)
LINQ offers two main syntaxes:
14
Query Syntax: This resembles SQL queries.
15
Method Syntax: This uses extension methods.
Example:
Here's a simple C# example demonstrating LINQ to Objects:
C#
using System;
using System.Linq;
using System.Collections.Generic;
public class LINQExample
{
public static void Main(string[] args)
{
List<int> numbers = new List<int> { 5, 10, 15, 20, 25, 30 };
// LINQ query to get even numbers greater than 10
var evenNumbers = from num in numbers
where num > 10 && num % 2 == 0
select num;
Console.WriteLine("Even numbers greater than 10:");
foreach (int number in evenNumbers)
{
Console.WriteLine(number);
}
//Example of method syntax doing the same thing.
var evenNumbersMethodSyntax = numbers.Where(num => num > 10 && num % 2 == 0);
Console.WriteLine("Even numbers greater than 10, using method syntax:");
foreach (int number in evenNumbersMethodSyntax)
{
Console.WriteLine(number);
}
}
}
24
Explanation:
We create a list of integers.
The LINQ query filters the list to get even numbers greater than 10.
The foreach loop iterates through the results and prints them to the console.
The second portion of the example, shows the same result, but using method syntax.
In essence, LINQ simplifies data querying and manipulation, making code more readable and
maintainable.16
17. Write a C# program that reads name, age and height of a person and store that info in database
named db_2020batch.
Ans:
C#
using System;
using System.Data.SqlClient;
public class PersonData
{
public static void Main(string[] args)
{
string connectionString = "Data Source=YourServerName;Initial
Catalog=db_2020batch;Integrated Security=True;"; // Replace with your server name
Console.Write("Enter Name: ");
string name = Console.ReadLine();
Console.Write("Enter Age: ");
if (!int.TryParse(Console.ReadLine(), out int age))
{
Console.WriteLine("Invalid age input. Age must be a number.");
return;
}
Console.Write("Enter Height (in cm): ");
if (!double.TryParse(Console.ReadLine(), out double height))
{
Console.WriteLine("Invalid height input. Height must be a number.");
return;
}
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string sql = "INSERT INTO People (Name, Age, Height) VALUES (@Name, @Age,
@Height)";
using (SqlCommand command = new SqlCommand(sql, connection))
{
25
command.Parameters.AddWithValue("@Name", name);
command.Parameters.AddWithValue("@Age", age);
command.Parameters.AddWithValue("@Height", height);
int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected > 0)
{
Console.WriteLine("Data inserted successfully!");
}
else
{
Console.WriteLine("Data insertion failed.");
}
}
}
}
catch (SqlException ex)
{
Console.WriteLine("Database error: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("An error occurred: " + ex.Message);
}
finally
{
Console.ReadKey();
}
}
}
Explanation and Important Notes:
1. Database Setup:
o Before running this code, ensure you have a SQL Server instance installed and
running.
o Create a database named db_2020batch.
o Create a table named People within the database with the following columns:
Name (VARCHAR or NVARCHAR, suitable length)
Age (INT)
Height (FLOAT or DECIMAL)
o Replace "YourServerName" in the connectionString with your actual SQL Server
instance name.
o If you are using SQL Server Authentication, you will need to change the connection
string to include the username and password.
2. Connection String:
o The connectionString is crucial for connecting to your database.
o Data Source: Specifies the SQL Server instance.
o Initial Catalog: Specifies the database name.
o Integrated Security=True: Uses Windows Authentication. If you need SQL Server
Authentication, replace this with User ID=yourUsername;Password=yourPassword;.
26
3. Input Handling:
o The code uses Console.ReadLine() to get input from the user.
o int.TryParse() and double.TryParse() are used to validate that the user's input for age
and height are valid numbers. This prevents runtime errors if the user enters non-
numeric data.
4. SQL Insertion:
o The INSERT INTO SQL statement is used to add the person's data to the People table.
o @Name, @Age, and @Height are parameters, which are used to prevent SQL
injection vulnerabilities.
o command.Parameters.AddWithValue() safely adds the user provided values to the
SQL command.
o command.ExecuteNonQuery() executes the SQL insert statement.
5. Error Handling:
o The try-catch block handles potential SqlException (database-related errors) and
general Exception (other errors).
o This is very important, as database operations can fail for many reasons.
o The finally block allows for the console to wait for a keypress, so the user can read the
output.
6. NuGet Package:
o You'll need to add the System.Data.SqlClient NuGet package to your project. In
Visual Studio, you can do this by going to "Tools" -> "NuGet Package Manager" ->
"Manage NuGet Packages for Solution," searching for "System.Data.SqlClient," and
installing it.
18. Write a program to show the execution sequence of constructor and destructor in multilevel
inheritance (include output). Use at least three levels of derivation.
Ans: C#
using System;
public class Grandparent
{
public Grandparent()
{
Console.WriteLine("Grandparent Constructor called.");
}
~Grandparent()
{
Console.WriteLine("Grandparent Destructor called.");
}
}
public class Parent : Grandparent
{
public Parent()
{
Console.WriteLine("Parent Constructor called.");
}
~Parent()
27
{
Console.WriteLine("Parent Destructor called.");
}
}
public class Child : Parent
{
public Child()
{
Console.WriteLine("Child Constructor called.");
}
~Child()
{
Console.WriteLine("Child Destructor called.");
}
}
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Creating Child object...");
Child child = new Child();
Console.WriteLine("Child object created.");
// Destructors are called when the object goes out of scope or is explicitly garbage collected.
// In this simple example, they are called when the Main method ends.
Console.WriteLine("End of Main method. Destructors will be called implicitly.");
}
}
/*
Output:
Creating Child object...
Grandparent Constructor called.
Parent Constructor called.
Child Constructor called.
Child object created.
End of Main method. Destructors will be called implicitly.
Child Destructor called.
Parent Destructor called.
Grandparent Destructor called.
*/
Explanation:
1. Multilevel Inheritance:
o The code demonstrates multilevel inheritance with three classes: Grandparent, Parent,
and Child.
o Parent inherits from Grandparent, and Child inherits from Parent.
28
2. Constructors:
o Each class has a constructor that prints a message indicating when it's called.
o When a Child object is created, the constructors are called in the order of inheritance:
Grandparent, Parent, and then Child.
o This ensures that the base class is initialized before the derived class.
3. Destructors:
o Each class also has a destructor (finalizer) that prints a message when it's called.
o Destructors are called when an object is garbage collected. In C#, the garbage
collector determines when to reclaim memory.
o Destructors are called in the reverse order of constructor invocation: Child, then
Parent, and finally Grandparent.
o This ensures that derived class resources are cleaned up before base class resources.
4. Execution Sequence:
o The output clearly shows the order of constructor and destructor calls.
o Constructors are called from the base class to the derived class.
o Destructors are called from the derived class to the base class.
5. Garbage Collection:
o In this simple example, the garbage collection and thus, the destructor calls, are
implicitly triggered when the Main method ends. In more complex scenarios, the
garbage collector might run at different times.
o It is not recommended to rely on the timing of garbage collection, and therefore,
destructor calls, for critical application logic.
19. Provide an example of how LINQ can be used to query data from a collection in C#.
Ans: C#
using System;
using System.Collections.Generic;
using System.Linq;
public class LinqExample
{
public static void Main(string[] args)
{
// Sample collection of integers
List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
// LINQ query to filter even numbers and square them
var squaredEvenNumbers = numbers
.Where(n => n % 2 == 0) // Filter even numbers
.Select(n => n * n); // Square each even number
// Display the results
Console.WriteLine("Squared even numbers:");
foreach (var number in squaredEvenNumbers)
{
Console.WriteLine(number);
}
// Another LINQ query to find the sum of all numbers greater than 5
int sumOfNumbersGreaterThan5 = numbers
29
.Where(n => n > 5)
.Sum();
Console.WriteLine($"\nSum of numbers greater than 5:
{sumOfNumbersGreaterThan5}");
// Example with a list of objects.
List<Person> people = new List<Person>
{
new Person { Name = "Alice", Age = 30 },
new Person { Name = "Bob", Age = 25 },
new Person { Name = "Charlie", Age = 35 },
new Person { Name = "David", Age = 28 }
};
// LINQ Query to find the names of people older than 28.
var olderPeopleNames = people
.Where(p => p.Age > 28)
.Select(p => p.Name);
Console.WriteLine("\nNames of people older than 28:");
foreach (var name in olderPeopleNames)
{
Console.WriteLine(name);
}
//LINQ Query to find the average age.
double averageAge = people.Average(p=> p.Age);
Console.WriteLine($"\nAverage age: {averageAge}");
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
}
Explanation:
1. using System.Linq;: This line imports the necessary LINQ namespace.
2. List<int> numbers = ...;: We create a sample list of integers.
3. numbers.Where(n => n % 2 == 0): This part of the LINQ query filters the numbers list,
selecting only the elements where n % 2 == 0 (i.e., even numbers). Where() takes a lambda
expression (n => n % 2 == 0) as an argument, which defines the filtering condition.
4. .Select(n => n * n): This part of the query transforms the filtered elements. Select() also takes
a lambda expression (n => n * n), which squares each even number.
5. foreach (var number in squaredEvenNumbers): This loop iterates through the resulting
squaredEvenNumbers collection and prints each squared even number.
30
6. numbers.Where(n => n > 5).Sum();: This query filters the numbers greater than 5 and then
calculates the sum of the filtered numbers using the Sum() method.
7. List<Person> people = ...;: This creates a list of Person objects.
8. people.Where(p => p.Age > 28).Select(p => p.Name);: This LINQ query filters the people
list, selecting only the Person objects where p.Age > 28, and then selects the Name property
of those objects.
9. people.Average(p => p.Age);: This LINQ query calculates the average age of the people in
the list.
10. Person class: A simple class to represent a person with Name and Age properties.
This example demonstrates how LINQ can be used to perform filtering, transformation, and
aggregation operations on collections in a concise and readable way.
20. Write a program to check whether the user age is greater than 18 or not showing "Eligible for
Vehicle license" implementing exception handling in your program.
Ans: C#
using System;
public class VehicleLicenseEligibility
{
public static void Main(string[] args)
{
try
{
Console.Write("Enter your age: ");
string input = Console.ReadLine();
if (!int.TryParse(input, out int age))
{
throw new FormatException("Invalid age format. Please enter a valid integer.");
}
if (age < 0)
{
throw new ArgumentOutOfRangeException("Age cannot be negative.");
}
if (age >= 18)
{
Console.WriteLine("Eligible for Vehicle license");
}
else
{
Console.WriteLine("Not eligible for Vehicle license");
}
}
catch (FormatException ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
catch (ArgumentOutOfRangeException ex)
31
{
Console.WriteLine($"Error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}
finally
{
Console.WriteLine("Program execution complete.");
}
}
}
Explanation and Key Improvements:
1. try-catch-finally Block:
o The core logic is enclosed in a try block.
o catch blocks handle potential exceptions:
FormatException: Catches errors if the user enters non-numeric input.
ArgumentOutOfRangeException: Catches errors if the user enters negative
numbers.
Exception: Catches any other unexpected exceptions.
o finally: Ensures that the "Program execution complete." message is always displayed,
regardless of whether an exception occurred.
2. int.TryParse():
o Instead of Convert.ToInt32(), int.TryParse() is used. This method attempts to parse the
input string into an integer.
o If the parsing is successful, it returns true, and the parsed integer is stored in the age
variable.
o If the parsing fails (e.g., the user enters "abc"), it returns false, and the
FormatException is thrown. This avoids runtime crashes.
3. Input Validation:
o Added a check to make sure the age is not negative. If a negative age is input, an
ArgumentOutOfRangeException is thrown.
4. Clear Error Messages:
o The catch blocks display informative error messages to the user, making it easier to
understand what went wrong.
5. Readability:
o The code is formatted for better readability.
6. Robustness:
o The added exception handling and input validation make the code more robust and
less prone to crashes.
21. Write a C# code to retrieve the data from the tblstudent as student_id, student_name,
student_address on the screen.
Ans: C#
using System;
using System.Data.SqlClient;
public class StudentDataRetriever
{
32
public static void Main(string[] args)
{
string connectionString = "Your_Connection_String_Here"; // Replace with your actual
connection string
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
string query = "SELECT student_id, student_name, student_address FROM
tblstudent";
using (SqlCommand command = new SqlCommand(query, connection))
{
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
Console.WriteLine("Student Data:");
Console.WriteLine("----------------------------------");
Console.WriteLine("{0,-10} {1,-20} {2,-30}", "Student ID", "Student Name",
"Student Address"); //Formatting the output
Console.WriteLine("----------------------------------");
while (reader.Read())
{
int studentId = reader.GetInt32(0);
string studentName = reader.GetString(1);
string studentAddress = reader.GetString(2);
Console.WriteLine("{0,-10} {1,-20} {2,-30}", studentId, studentName,
studentAddress);
}
}
else
{
Console.WriteLine("No student data found.");
}
}
}
}
}
catch (SqlException ex)
{
Console.WriteLine("Error retrieving student data: " + ex.Message);
}
catch (Exception ex)
{
33
Console.WriteLine("An unexpected error occurred: " + ex.Message);
}
finally
{
Console.WriteLine("Operation Completed");
}
}
}
Explanation and Key Improvements:
1. Connection String:
o Replace "Your_Connection_String_Here" with your actual SQL Server connection
string. This string contains information about your server, database, and authentication
method. Example: "Data Source=YourServerName;Initial
Catalog=YourDatabaseName;User ID=YourUsername;Password=YourPassword;" or
"Data Source=YourServerName;Initial Catalog=YourDatabaseName;Integrated
Security=True;"
2. using Statements:
o The using statements ensure that the SqlConnection, SqlCommand, and
SqlDataReader objects are properly disposed of, even if exceptions occur. This is
crucial for releasing database resources.
3. Error Handling:
o The try-catch blocks handle potential SqlException (database-specific errors) and
general Exception (other errors). This makes the code more robust.
4. reader.HasRows Check:
o The reader.HasRows check prevents the code from trying to read data when the query
returns no results, avoiding potential errors.
5. Formatted Output:
o The Console.WriteLine("{0,-10} {1,-20} {2,-30}", ...) lines format the output to make
it more readable. The negative numbers in the format string specify left alignment and
field widths.
6. Data Type Retrieval:
o The Code now uses the correct datatypes when retrieving the data from the reader.
reader.GetInt32(0) is used for the student_id, and reader.GetString(1) and
reader.GetString(2) are used for the student name and address, respectively. This
prevents type conversion errors.
7. Finally Block:
o The finally block is added to ensure the message "Operation Completed" is always
outputted regardless of whether an exception occurs.
22. Write a program to create a C# form that takes customer id, customer name, customer address
and two button as "submit" and "cancel". When user clicks on submit button, the entered data
should be stored into a table "tblcustomer".
Ans:
using System;
using System.Data.SqlClient;
using System.Windows.Forms;
namespace CustomerFormApp
{
public partial class CustomerForm : Form
34
{
public CustomerForm()
{
InitializeComponent();
}
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.txtCustomerId = new System.Windows.Forms.TextBox();
this.txtCustomerName = new System.Windows.Forms.TextBox();
this.txtCustomerAddress = new System.Windows.Forms.TextBox();
this.btnSubmit = new System.Windows.Forms.Button();
this.btnCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(65, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Customer ID:";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 36);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(85, 13);
this.label2.TabIndex = 1;
this.label2.Text = "Customer Name:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 63);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(95, 13);
this.label3.TabIndex = 2;
this.label3.Text = "Customer Address:";
//
// txtCustomerId
//
this.txtCustomerId.Location = new System.Drawing.Point(113, 6);
this.txtCustomerId.Name = "txtCustomerId";
this.txtCustomerId.Size = new System.Drawing.Size(200, 20);
35
this.txtCustomerId.TabIndex = 3;
//
// txtCustomerName
//
this.txtCustomerName.Location = new System.Drawing.Point(113, 33);
this.txtCustomerName.Name = "txtCustomerName";
this.txtCustomerName.Size = new System.Drawing.Size(200, 20);
this.txtCustomerName.TabIndex = 4;
//
// txtCustomerAddress
//
this.txtCustomerAddress.Location = new System.Drawing.Point(113, 60);
this.txtCustomerAddress.Name = "txtCustomerAddress";
this.txtCustomerAddress.Size = new System.Drawing.Size(200, 20);
this.txtCustomerAddress.TabIndex = 5;
//
// btnSubmit
//
this.btnSubmit.Location = new System.Drawing.Point(113, 90);
this.btnSubmit.Name = "btnSubmit";
this.btnSubmit.Size = new System.Drawing.Size(75, 23);
this.btnSubmit.TabIndex = 6;
this.btnSubmit.Text = "Submit";
this.btnSubmit.UseVisualStyleBackColor = true;
this.btnSubmit.Click += new System.EventHandler(this.btnSubmit_Click);
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(238, 90);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 7;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// CustomerForm
//
this.ClientSize = new System.Drawing.Size(350, 130);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnSubmit);
this.Controls.Add(this.txtCustomerAddress);
this.Controls.Add(this.txtCustomerName);
this.Controls.Add(this.txtCustomerId);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Name = "CustomerForm";
this.Text = "Customer Details";
this.ResumeLayout(false);
36
this.PerformLayout();
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtCustomerId;
private System.Windows.Forms.TextBox txtCustomerName;
private System.Windows.Forms.TextBox txtCustomerAddress;
private System.Windows.Forms.Button btnSubmit;
private System.Windows.Forms.Button btnCancel;
private void btnSubmit_Click(object sender, EventArgs e)
{
string customerId = txtCustomerId.Text;
string customerName = txtCustomerName.Text;
string customerAddress = txtCustomerAddress.Text;
string connectionString = "Your_Connection_String"; // Replace with your actual
connection string.
string query = "INSERT INTO tblcustomer (CustomerID, CustomerName,
CustomerAddress) VALUES (@CustomerID, @CustomerName, @CustomerAddress)";
using (SqlConnection connection = new SqlConnection(connectionString))
{
using (SqlCommand command = new SqlCommand(query, connection))
{
command.Parameters.AddWithValue("@CustomerID", customerId);
command.Parameters.AddWithValue("@CustomerName", customerName);
command.Parameters.AddWithValue("@CustomerAddress", customerAddress);
try
{
connection.Open();
command.ExecuteNonQuery();
MessageBox.Show("Data inserted successfully!");
txtCustomerId.Clear();
txtCustomerName.Clear();
txtCustomerAddress.Clear();
}
catch (Exception ex)
{
MessageBox.Show("Error: " + ex.Message);
}
}
}
}
37
private void btnCancel_Click(object sender, EventArgs e)
{
txtCustomerId.Clear();
txtCustomerName.Clear();
txtCustomerAddress.Clear();
}
}
}
“The End”
38