C Sharp
C Sharp
C#
C# (C-Sharp) is a programming language developed by Microsoft that runs on the .NET
Framework.
C# is pronounced "C-Sharp".
C# has roots from the C family, and the language is close to other popular languages
like C++ and Java.
The first version was released in year 2002. The latest version, C# 12, was released in
November 2023.
C# is used for:
• Mobile applications
• Desktop applications
• Web applications
• Web services
• Web sites
• Games
• VR
• Database applications
• And much, much more!
Applications written in C# use the .NET Framework, so it makes sense to use Visual Studio,
as the program, the framework, and the language, are all created by Microsoft.
Comments
can be used to explain C# code, and to make it more readable. It can also be used to
prevent execution when testing alternative cod
Single-line Comments
Single-line comments start with two forward slashes (//).
Multi-line Comments
Multi-line comments start with /* and ends with */.
Namespace
Namespaces play an important role in managing related classes in C#. The .NET
Framework uses namespaces to organize its built-in classes. For example, there
are some built-in namespaces in .NET such as System, System.Linq,
System.Web, etc. Each namespace contains related classes.
C# Variables
Variables are containers for storing data values.
In C#, there are different types of variables (defined with different keywords), for example:
• int - stores integers (whole numbers), without decimals, such as 123 or -123
• double - stores floating point numbers, with decimals, such as 19.99 or -19.99
• char - stores single characters, such as 'a' or 'B'. Char values are surrounded by single
quotes
• string - stores text, such as "Hello World". String values are surrounded by double
quotes
• bool - stores values with two states: true or false
var
C# 3.0 introduced var keyword to declare method level variables without
specifying a data type explicitly.
var can be used to declare any built-in data type or a user-defined type or an
anonymous type variable.
Constants
which means unchangeable and read-only:
you can add the const keyword in front of the variable type. PI (3.14159...).
Struct
C#, struct is the value type data type that represents data structures. It can
contain a parameterized constructor, static constructor, constants, fields,
methods, properties, indexers, operators, events, and nested types.
can be used to hold small data values that do not require inheritance, e.g.
struct
coordinate points, key-value pairs, and complex data structure.
When to Use Structs in C# Structs are best used when you need to represent
simple data types, such as integers, strings, or other basic data types. They are
also useful when you need to work with large datasets, such as arrays or lists,
where performance is critical.
Use struct
Display Variables
The WriteLine() method is often used to display variable values to the console window.
int x = 5, y = 6, z = 50;
Console.WriteLine(x + y + z);
C# Identifiers
All C# variables must be identified with unique names.
Identifiers can be short names (like x and y) or more descriptive names (age, sum,
totalVolume).
C# Data Types
As explained in the variables chapter, a variable in C# must be a specified data type:
C# Type Casting
Type casting is when you assign a value of one data type to another type.
User Input
• You have already learned that Console.WriteLine() is used to output (print) values. Now
we will use Console.ReadLine() to get user input.
• In the following example, the user can input his or hers username, which is stored in
the variable userName.
• The Console.ReadLine() method returns a string.
Console.WriteLine("Enter your age:");
int age = Console.ReadLine();
Operators
Operators are used to perform operations on variables and values.
Assignment Operators
Assignment operators are used to assign values to variables.
Comparison Operators
Comparison operators are used to compare two values (or variables).
Logical Operators
As with comparison operators, you can also test for True or False values with logical
operators.
C# Strings
Strings are used for storing text.
You can also use the string.Concat() method to concatenate two strings:
String Interpolation ; string name = $"My full name is: {firstName} {lastName}";
Access Strings ;\
string myString = "Hello";
Another useful method is Substring(), which extracts the characters from a string, starting
from the specified character position/index, and returns a new string. This method is often
used together with IndexOf() to get the specific character position:
StringBuilder
The StringBuilder doesn't create a new object in the memory but dynamically
expands memory to accommodate the modified string.
This behavior would hinder the performance if the original string changed
multiple times by replacing, appending, removing, or inserting new strings in
the original string.
1. StringBuilder is mutable.
2. StringBuilder performs faster than string when appending multiple string
values.
3. Use StringBuilder when you need to append more than three or four strings.
4. Use the Append() method to add or append strings to the StringBuilder object.
5. Use the ToString() method to retrieve a string from the StringBuilder object.
String (capital S) is a class in the .NET framework in the System namespace. The
fully qualified name is System.String. Whereas, the lower case string is an alias
of System.String.
C# Booleans
C# has a bool data type, which can take the values true or false.
• YES / NO
• ON / OFF
• TRUE / FALSE
Nullable types
Nullable types represent the Null value as well the actual range of that data type.
Anonymous Type
Example: Anonymous Type
var student = new { Id = 1, FirstName = "James", LastName = "Bond" };
• an anonymous type is a type (class) without any name that can contain
public read-only properties only. It cannot contain other members, such as
fields, methods, events, etc.
• You create an anonymous type using the new operator with an object
initializer syntax. The implicitly typed variable- var is used to hold the
reference of anonymous types.
Dynamic Types
• C# 4.0 (.NET 4.5) introduced a new type called dynamic that avoids compile-
time type checking. A dynamic type escapes type checking at compile-time;
instead, it resolves type at run time.
• A dynamic type variables are defined using the dynamic keyword.
Asynchronous Programming?
In asynchronous programming, the code gets executed in a thread without having
to wait for an I/O-bound or long-running task to finish.
Use async along with await and Task if the async method returns a value back to the
calling code. We used only the async keyword in the above program to
demonstrate the simple asynchronous void method.
The await keyword waits for the async method until it returns a value. So the main
application thread stops there until it receives a return value.
The Task class represents an asynchronous operation
and Task<TResult> generic class represents an operation that can return a value.
In the above example, we used await Task.Delay(4000) that started async operation
that sleeps for 4 seconds and await holds a thread until 4 seconds.
The difference is that the value of a static readonly field is set at run time,
and can thus be modified by the containing class, whereas the value of a
const field is set to a compile-time constant
Value of the static members can be modified Readonly variable cannot be modified Constant variables
using ClassName.StaticMemberName . at run-time. It can only be initialized or cannot be modified after
changed in the constructor. declaration.
1. Value type
2. Reference type
3. Pointer type
Value Type
A data type is a value type if it holds a data value within its own memory
space. It means the variables of these data types directly contain values.
All the value types derive from System.ValueType, which in-turn, derives from System.Object.
Reference Type
a reference type doesn't store its value directly. Instead, it stores the address
where the value is being stored. In other words, a reference type contains a
pointer to another memory location that holds the data.
out keyword
The out keyword can be used with variables and method parameters. The
out paramters are always passed by reference for both, the value type and
the reference type data types.
What is boxing?
Boxing is the process of converting a value type to the object type or any interface
type implemented by this value type. Boxing is implicit.
Boxing
int i = 10;
object o = i; //performs boxing
As you know, all the reference types stored on heap where it contains the address
of the value and value type is just an actual value stored on the stack
What is Unboxing?
Unboxing is the reverse of boxing. It is the process of converting a reference type
to value type. Unboxing extract the value from the reference type and assign it
to a value type.
Example: Unboxing
object o = 10;
int i = (int)o; //performs unboxing
Note:
Boxing and unboxing degrade the performance. So, avoid using it. Use generics to avoid
boxing and unboxing. For example, use List instead of ArrayList.
Switch Statements
Use the switch statement to select one of many code blocks to be executed.
While Loop
Loops
• Loops can execute a block of code as long as a specified condition is reached.
• Loops are handy because they save time, reduce errors, and they make code more
readable.
While Loop
• The while loop loops through a block of code as long as a specified condition is True:
• the code in the loop will run, over and over again, as long as a variable (i) is less than
Note: Do not forget to increase the variable used in the condition, otherwise the loop
will never end!
Do/While Loop
The do/while loop is a variant of the while loop. This loop will execute the code block once,
before checking if the condition is true, then it will repeat the loop as long as the condition is
true.
Do not forget to increase the variable used in the condition, otherwise the loop will
never end!
For Loop
When you know exactly how many times you want to loop through a block of code, use
the for loop instead of a while loop:
for (statement 1; statement 2; statement 3)
Statement 1 is executed (one time) before the execution of the code block.
Statement 2 defines the condition for executing the code block.
Statement 3 is executed (every time) after the code block has been executed.
Nested Loops
It is also possible to place a loop inside another loop. This is called a nested loop.
The "inner loop" will be executed one time for each iteration of the "outer loop":
Break
You have already seen the break statement used in an earlier chapter of this tutorial. It was
used to "jump out" of a switch statement.
Continue
The continue statement breaks one iteration (in the loop), if a specified condition occurs, and
continues with the next iteration in the loop.
Array
Arrays are used to store multiple values in a single variable, instead of declaring separate
variables for each value.
Note: Array indexes start with 0: [0] is the first element. [1] is the second element, etc.
An array is the data structure that stores a fixed number of literal values
(elements) of the same data type. Array elements are stored contiguously in the
memory.
Sort an Array
There are many array methods available, for example Sort(), which sorts an array
alphabetically or in an ascending order:
Two-Dimensional Arrays
To create a 2D array, add each array within its own set of curly braces, and insert a comma
(,) inside the square brackets:
multidimensional arrays.
Arrays can have any number of dimensions. The most common are two-dimensional arrays
(2D).
Methods
A method is a block of code which only runs when it is called.
Methods are used to perform certain actions, and they are also known as functions.
Why use methods? To reuse code: define the code once, and use it many times…
They are specified after the method name, inside the parentheses. You can add as many
parameters as you want, just separate them with a comma.
Console.WriteLine(country);
}
Return Values
In the previous page, we used the void keyword in all examples, which indicates that the
method should not return a value.
If you want the method to return a value, you can use a primitive data type (such
as int or double) instead of void, and use the return keyword inside the method:
Named Arguments
It is also possible to send arguments with the key: value syntax.
Method Overloading
With method overloading, multiple methods can have the same name with different
parameters:
Note: Multiple methods can have the same name as long as the number and/or type of
parameters are different.
An object is basically a block of memory that has been allocated and configured
according to the blueprint.
Class Members
Fields and methods inside classes are often referred to as "Class Members":
Access Modifiers
Modifier Description
protected The code is accessible within the same class, or in a class that is inherited
internal The code is only accessible within its own assembly, but not from another assemb
To achieve "Encapsulation" - which is the process of making sure that "sensitive" data is
hidden from users. This is done by declaring fields as private. You will learn more about this
in the next chapter.
Properties
Enums
An enum is a special "class" that represents a group
of constants (unchangeable/read-only variables).
To create an enum, use the enum keyword (instead of class or interface), and
separate the enum items with a comma:
Exceptions
When executing C# code, different errors can occur: coding errors made by the
programmer, errors due to wrong input, or other unforeseeable things.
When an error occurs, C# will normally stop and generate an error message. The technical
term for this is: C# will throw an exception (throw an error).
Exception Handling
exception handling in C# using try, catch, and finally blocks.
The catch statement allows you to define a block of code to be executed, if an error occurs in
the try block.
Finally
The finally statement lets you execute code, after try...catch, regardless of the result:
The throw keyword
The throw statement allows you to create a custom error.
The throw statement is used together with an exception class. There are many exception
classes available in
C#: ArithmeticException, FileNotFoundException, IndexOutOfRangeException, TimeOutException, etc:
An exception can be raised manually by using the throw keyword. Any type of
exceptions which is derived from Exception class can be raised using the throw
keyword.
Custom exceptions
Custom exceptions are a powerful feature of . NET C# that allows you to handle
errors and unexpected situations in your application in a more specific way.
IndexOutOfRangeException
NullReferenceException
Interface
In the human world, a contract between the two or more humans binds them to
act as per the contract. In the same way, an interface includes the declarations
of related functionalities. The entities that implement the interface must provide
the implementation of declared functionalities.
In C#, an interface can be defined using the interface keyword. An interface can
contain declarations of methods, properties, indexers, and events. However, it
cannot contain instance fields.
Static methods can be defined using the static keyword before a return type and after
an access modifier. Static methods can be overloaded but cannot be overridden. Static
methods can contain local static variables. Static methods cannot access or call non-
static variables unless they are explicitly passed as parameters.
Indexers ;
Indexers allow instances of a class or struct to be indexed just like arrays.
An indexer is a special type of property that allows a class or a structure to be
accessed like an array for its internal collection. C# allows us to define custom
indexers, generic indexers, and also overload indexers.
An indexer can be defined the same way as property with this keyword and square
brackets [].
Note:
Indexer does not allow ref and out paramters.
Generics
generic means not specific to a particular data type.
• List: In Generic List, we have to specify a data type to its contents, and all elements will have
the same datatype. ...
• Dictionary , Sorted List , Stack: ...
• Queue , ArrayList , HashTable ,Sorted List:
There are two types of collections available in C#: non-generic collections and
generic collections.
Tuple
The Tuple<T> class was introduced in .NET Framework 4.0. A tuple is a data
structure that contains a sequence of elements of different data types. It can be
used where you want to have a data structure to hold an object with properties,
but you don't want to create a separate type for it.
USES ;
Tuples in C# are utilized for returning multiple values from methods, passing multiple values as a single
parameter, and temporary storage without defining a separate class.
Tuple Limitations:
Tuples in C# are reference types, allocated on the heap, potentially leading to CPU-
intensive operations; limited to eight elements and require nested tuples for additional
elements, risking ambiguity; accessed via properties with naming patterns like
Item<elementNumber>, which might not be intuitive.
Delegates
What if we want to pass a function as a parameter? How does C# handles the
callback functions or event handler? The answer is - delegate.
The delegate is a reference type data type that defines the method signature.
You can define variables of delegate, just like other data type, that can refer to
any method with the same signature as the delegate.
1. Declare a delegate
2. Create an instance and reference a method
3. Invoke a delegate
1. Delegate is the reference type data type that defines the signature.
2. Delegate type variable can refer to any method with the same signature as
the delegate.
Action Delegate
Action is a delegate type defined in the System namespace. An Action type delegate
is the same as Func delegate except that the Action delegate doesn't return a
value. In other words, an Action delegate can be used with a method that has a
void return type.
Anonymous Method
1. Anonymous method can be defined using the delegate keyword
2. Anonymous method must be assigned to a delegate.
3. Anonymous method can access outer variables or functions.
4. Anonymous method can be passed as a parameter.
5. Anonymous method can be used as event handlers.
Events
Delegate Event
A delegate is declared using the delegate keyword. An event is declared using the event
keyword.
Delegate is a function pointer. It holds the reference of The event is a notification mechanism that
one or more methods at runtime. depends on delegates
}
public class Big: Small
{
}
public class Bigger : Big
{
Extension Method
Extension methods are a powerful feature in C# that allows you to add new
functionality to existing types without modifying their source code.
Points to Remember :
1. Extension methods are additional custom methods which were originally not
included with the class.
2. Extension methods can be added to custom, .NET Framework or third party
classes, structs or interfaces.
3. The first parameter of the extension method must be of the type for which
the extension method is applicable, preceded by the this keyword.
4. Extension methods can be used anywhere in the application by including the
namespace of the extension method.
Stream
C# includes following standard IO (Input/Output) classes to read/write from
different sources like files, memory, network, isolated storage, etc.
File
C# includes static File class to perform I/O operation on physical file system. The
static File class includes various utility method to interact with physical file of any
type e.g. binary, text etc.
Points to Remember :
1. File is a static class to read\write from physical file with less coding.
2. Static File class provides functionalities such as create, read\write, copy,
move, delete and others for physical files.
3. Static Directory class provides functionalities such as create, copy, move,
delete etc for physical directories with less coding.
4. FileInfo and DirectoryInfo class provides same functionality as static File and
Directory class.
Thus you can use FileInfo, StreamReader and StreamWriter class to read/write
contents from physical file.
Object Initializer Syntax
C# 3.0 (.NET 3.5) introduced Object Initializer Syntax, a new way to initialize an
object of a class or collection. Object initializers allow you to assign values to the
fields or properties at the time of creating an object without invoking a
constructor.
Advantages of Initializers
• Initializer syntax makes a code more readable, easy to add elements into the
collection.
• Useful in multi-threading.
Design Principle
SOLID design principles in C# are basic design principles. SOLID stands
for Single Responsibility Principle (SRP), Open closed Principle (OSP),
Liskov substitution Principle (LSP), Interface Segregation Principle (ISP), and
Dependency Inversion Principle (DIP).
Design Pattern
Design Pattern provides low-level solutions related to implementation, of
commonly occurring object-oriented problems. In other words, design
pattern suggests a specific implementation for the specific object-oriented
programming problem.
For example, if you want to create a class that can only have one
object at a time, then you can use the Singleton design pattern which
suggests the best way to create a class that can only have one object.
Design patterns are tested by others and are safe to follow, e.g. Gang of
Four patterns: Abstract Factory, Factory, Singleton, Command, etc.
How to calculate the code execution time
Hashtable Dictionary
Hashtable is included in Dictionary is included in
the System.Collections namespace. the System.Collections.Generic namespace.