Unit II
Unit II
Struct or structure
A struct type is a value type that is typically used to encapsulate small groups of related
variables such as the coordinates of a rectangle and all. They are basically for light-weighted
objects. Unlike class, structs in C# are value type than a reference type. It is useful if you
have data that is not intended to be modified after the creation of the struct. Structs contain
methods, properties, indexers, and so on. It can not contain default constructors.
Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp15
{
Enum:
The enum is a keyword that is used to declare an enumeration. Enumeration is a type that
consists of a set of named constant called enumerators.
By default the first enumerator has the value of “0” and the value of each successive
enumerator is increased by one.
Like:
• A class is a blueprint of an object that contains variables for storing data and functions
to
perform operations on the data.
• Or
• A class is a collection of member variables and member functions.
• A class will not occupy any memory space and hence it is only a logical
representation of data.
Class:
A class definition starts with the keyword class followed by the class name; and
the class body enclosed by a pair of curly braces. Following is the general form of a class
definition:
class class_name
{
Variable declaration;
Methods declaration;
}
Class is keyword
Class name is any C# valid identifier.
Everything inside the square brackets is called body of the class .It is optional.
Inheritance:
• (Acquiring (taking) the properties of one class into another class is called inheritance.
• (Or) When a new class needs same members as an existing class, then instead of
creating those members again in new class, the new class can be created from existing
class, which is called as inheritance.
• Syntax:
class derived-class-name: base-class-name
{ Members of class }
Types of inheritance: Inheritance can be classified into 5 types
1. Single Inheritance
2. Hierarchical Inheritance
3. Multi-Level Inheritance
4. Hybrid Inheritance
5. Multiple Inheritance
class Parent
{
public void Earning()
{
Console.WriteLine("Parent.Earning");
}
}
class Child : Parent
{
public void Inherit()
{
Console.WriteLine("Child..Inherit");
}
}
internal class Program
{
static void Main(string[] args)
{
Parent parent = new Parent();
Child child = new Child();
child.Earning();
child.Inherit();
}
}
}
Output : Parent..Earning
Child..Inherit
ABSTRACT CLASS:
In c sharp Abstract class is defined using "abstract" keyword.
• When a class contains at least one abstract method, then the class must be
declared as abstract class.
• If an Abstract class contain any abstract methods, then those methods must be
implemented under the child class using override modifier.
Characteristics of abstract classes:
1. Abstract Class cannot be instantiated directly.
2. Abstract Class can have both abstract methods and non-abstract methods.
3. If any child class of abstract class wants to consume non abstract method of its
parent, first
they require to implement all the abstract methods of parent otherwise consuming non
abstract methods of parent will not be possible.
4. An abstract class can consume only by child classes that to after providing the
implementation for all the abstract methods of abstract class.
5. You cannot declare an abstract method outside an abstract class
6. When a class is declared sealed, it cannot be inherited, abstract classes cannot be
declared sealed.
Syntax: abstract class class1
{
public abstract void add(int x, int y);
}
Example:
Class Calculator : class1{
public override void add(int x, int y){}
Method Overloading:-
Method Overloading is the common way of implementing polymorphism. It is the
ability to redefine a function in more than one form. A user can implement function
overloading by defining two or more functions in a class sharing the same name. C#
can distinguish the methods with different method signatures. i.e. the methods can
have the same name but with different parameters list (i.e. the number of the
parameters, order of the parameters, and data types of the parameters) within the
same class.
Overloaded methods are differentiated based on the number and type of
the parameters passed as arguments to the methods.
You can not define more than one method with the same name, Order and
the type of the arguments. It would be compiler error.
The compiler does not consider the return type while differentiating the
overloaded method. But you cannot declare two methods with the same
signature and different return type. It will throw a compile-time error. If
both methods have the same parameter types, but different return type,
then it is not possible.
Why do we need Method Overloading?
If we need to do the same kind of the operation in different ways i.e. for different
inputs. In the example described below, we are doing the addition operation for
different inputs. It is hard to find many different meaningful names for single action.
Different ways of doing overloading methods-
Method overloading can be done by changing:
1. The number of parameters in two methods.
2. The data types of the parameters of methods.
3. The Order of the parameters of methods.
Example:
using System;
class Tester {
// Main Method
public static void Main(String[] args)
{
// Creating Object
Tester ob = new Tester();
Output:
sum of the two integer value : 3
sum of the three integer value : 6
Constructor overloading:
Using System;
Namespace ns{
class ADD {
int x, y;
double f;
string s;
// 1st constructor
public ADD(int a, double b)
{
x = a;
f = b;
}
// 2nd constructor
public ADD(int a, string b)
{
y = a;
s = b;
}
class ConstructorOverloading {
// Main Method
static void Main()
{
Output:
1st constructor (int + float): 30.2
2nd constructor (int + string): Roll No. is 10
Operator Overloading:-
The concept of overloading a function can also be applied to operators. Operator
overloading gives the ability to use the same operator to do various operations. It
provides additional capabilities to C# operators when they are applied to user-
defined data types. It enables to make user-defined implementations of various
operations where one or both of the operands are of a user-defined class. Only the
predefined set of C# operators can be overloaded.
Syntax:-
access specifier className operator Operator_symbol (parameters)
{
// Code
}
Note :
Operators Overloadability
+, -, *, /, %, &, |, <<, >> All C# binary operators can be overloaded.
+, -, !, ~, ++, --, true, false All C# unary operators can be overloaded.
==, !=, <, >, <= , >= All relational operators can be overloaded, but only as pairs.
The function call bounded to the class at the time of compilation, if the function is going to be
executed from a different class (Parent Class) at run-time rather than the class bounded at
compilation-time, then it is called Run-Time Polymorphism. This happens in the case of Method
Overriding because, in the case of Overriding, we have multiple methods with the same signature
i.e. Parent Class and the Child class having the same method implementation. So, in this case, we
will be able to know at runtime from which class the method is going to be executed.
It is also called Dynamic Polymorphism or Late Binding as at Run-time we will be able to know
from which class the method is going to be executed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp21
{
class Parent
{
public virtual void sleepWalk()
{
Console.WriteLine("Parent..Behavior..sleep walk");
}
}
class Child: Parent
{
public override void sleepWalk()
{
Console.WriteLine("Child..Behavior..sleep walk");
}
}
internal class Program
{
static void Main(string[] args)
{
Parent parent;
parent= new Parent();
parent.sleepWalk();
parent = new Child();
parent.sleepWalk();
}
}
}
namespace ConsoleApp16
{
class Complex
{
private int x;
private int y;
public Complex()
{
}
public Complex(int i, int j)
{
x = i;
y = j;
}
public void ShowXY()
{
Console.WriteLine("{0} {1}", x, y);
}
public static Complex operator -(Complex c)
{
Complex temp = new Complex();
temp.x = -c.x;
temp.y = -c.y;
return temp;
}
}
internal class Program
{
Garbage collector (GC) : It manages the allocation and release of memory. The
garbage collector serves as an automatic memory manager.
You do not need to know how to allocate and release memory or manage the lifetime
of the objects that use that memory.
An allocation is made any time you declare an object with a “new” keyword or a value
type is boxed. Allocations are typically very fast.
When there isn’t enough memory to allocate an object, the GC must collect and
dispose of garbage memory to make memory available for new allocations.
When objects are no longer used then it will reclaim those objects by clearing their
memory, and keeps the memory available for future allocations.
Managed objects automatically get clean content to start with, so their constructors do
not have to initialize every data field.
interfaces:
interface <interface_name >
{
// declare Events
// declare indexers
// declare methods
// declare properties
}
Syntax for Implementing Interface:
class class_name : interface_name
To declare an interface, use interface keyword. It is used to provide total abstraction.
A namespace
is designed for providing a way to keep one set of names separate from another. The class
names declared in one namespace does not conflict with the same class names declared in
another.
Defining a Namespace
A namespace definition begins with the keyword namespace followed by the namespace
name as follows −
namespace namespace_name {
// code declarations
}
To call the namespace-enabled version of either function or variable, prepend the namespace
name as follows −
namespace_name.item_name;
The following program demonstrates use of namespaces −
using System;
namespace first_space {
class namespace_cl {
public void func() {
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space {
class namespace_cl {
public void func() {
Console.WriteLine("Inside second_space");
}
}
}
class TestClass {
static void Main(string[] args) {
first_space.namespace_cl fc = new first_space.namespace_cl();
second_space.namespace_cl sc = new second_space.namespace_cl();
fc.func();
sc.func();
Console.ReadKey();
}
}
When the above code is compiled and executed, it produces the following result −
Inside first_space
Inside second_space
preprocessor directives:-
The preprocessor directives give instruction to the compiler to preprocess the information
before actual compilation starts.
All preprocessor directives begin with #, and only white-space characters may appear before
a preprocessor directive on a line. Preprocessor directives are not statements, so they do not
end with a semicolon (;).
#define PI
using System;
namespace PreprocessorDAppl {
class Program {
static void Main(string[] args) {
#if (PI)
Console.WriteLine("PI is defined");
#else
Console.WriteLine("PI is not defined");
#endif
Console.ReadKey();
}
}
}
When the above code is compiled and executed, it produces the following result −
PI is defined
namespace preprocessor3
{
class Program
{
static void Main( string[] args )
{
char ch = 'y';
Output:
Value of ch is 'y'
Using #pragma warning and #pragma checksum In the code below we use
the #pragma warning disable to disable all warnings. Inside main, we generate a
user defined warning to check if it has been disabled or not. And #pragma checksum
is used to aid the debugging of the file.
// C# program to Disables all warnings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Preprocessor4 {
class Program {
static void Main(string[] args)
{
// Creating a warning
#warning "This is disabled"
Exception Handling:
C# exception handling is built upon four keywords: try, catch, finally, and throw.
try − A try block identifies a block of code for which particular exceptions is activated. It is
followed by one or more catch blocks.
catch − A program catches an exception with an exception handler at the place in a program
where you want to handle the problem. The catch keyword indicates the catching of an
exception.
finally − The finally block is used to execute a given set of statements, whether an exception
is thrown or not thrown. For example, if you open a file, it must be closed whether an
exception is raised or not.
throw − A program throws an exception when a problem shows up. This is done using a
throw keyword.
Example:
int[] arr = { 1, 2, 3, 4, 5 };
Threads:- A thread is defined as the execution path of a program. Each thread defines a unique
flow of control. If your application involves complicated and time consuming operations, then it is
often helpful to set different execution paths or threads, with each thread performing a particular job.
class program
{
public void WorkThreadFunction()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Simple Thread");
}
}
}
class threprog
{
public static void Main()
{
program pg = new program();
Thread thread = new Thread(new ThreadStart(pg.WorkThreadFunction));
thread.Start();
Console.Read();
}
}
Explanation
This C# Program, we are creating a new ThreadStart delegate. The delegate points to a method
that will be executed by the new thread. Pass this delegate as a parameter when creating a new
Thread instance. Finally, call the Thread.Start method to run the method.
Stream
When you open a file for reading or writing, it becomes stream. Stream is a sequence of bytes
traveling from a source to a destination over a communication path.
The two basic streams are input and output streams. Input stream is used to read and output
stream is used to write.
The parent class of file processing is stream. Stream is an abstract class, which is used as the
parent of the classes that actually implement the necessary operations.
The primary support of a file as an object is provided by a .NET Framework class called File.
This static class is equipped with various types of (static) methods to create, save, open, copy,
move, delete, or check the existence of a file.
The following table describes some commonly used classes in the System.IO namespace.
FileStream It is used to read from and write to any location within a file
The StreamWriter class in inherited from the abstract class TextWriter. The TextWriter class
represents a writer, which can write a series of characters.
The following table describes some of the methods used by StreamWriter class.
Methods Description
Close Closes the current StreamWriter object and the underlying stream
Clears all buffers for the current writer and causes any buffered data to be written
Flush
to the underlying stream
WriteLine Writes data specified by the overloaded parameters, followed by end of line
StreamReader Class
The StreamReader class is inherited from the abstract class TextReader. The TextReader
class represents a reader, which can read series of characters.
Methods Description
Closes the object of StreamReader class and the underlying stream, and release any
Close
system resources associated with the reader
Peek Returns the next available character but doesn't consume it
Read Reads the next character or the next set of characters from the stream
ReadLine Reads a line of characters from the current stream and returns data as a string
Seek Allows the read/write position to be moved to any position with the file