Professional Documents
Culture Documents
Before moving ahead I would recommend watching videos from below image
for full in depth topics. Just click on the below image you would be navigated
to the Videos.
https://www.youtube.com/playlist?
list=PLqGM4JWKUx3cZKGoy4J9vX4DCBOOjRhJe
Day 4 Agenda
1.
2.
3.
4.
Delegates
Enums
Attributes
Generics
Delegates
Syntax:
When you want to use the Class in C# you do in following ways, you first
define the class (properties, methods) and then you instantiate the class
using object. With delegate its the same process. You first declare the
Delegate as shown above i.e. what kind of type will delegate represent.
Then, we have to create one or more instances of that delegate. Lets make
a small program defining the definition that Delegate as type safe pointer to
a function. We will learn how to declare a Delegate, creating object of
Delegate and how to invoke the Delegate.
using System;
namespace Delegates
Output:
Output:
class Program
{
static void Main(string[] args)
{
Employee obj = new Employee();
obj.PrintInformation(1, "Saillesh");
}
}
Output:
Eg 2:
using System;
namespace Delegates
{
class Calculation
{
public double Sum(int Num1, int Num2, int Num3)
{
return Num1 + Num2 + Num3;
}
public double Multiplication(int Num1, int Num2, int Num3)
{
return Num1 * Num2 * Num3;
}
}
class Program
{
static void Main(string[] args)
double Result;
Calculation obj = new Calculation();
Result = obj.Sum(10, 20, 30);
Console.WriteLine("The sum is={0}", Result);
Result = obj.Multiplication(2,3,4);
Console.WriteLine("The multiplication result is={0}", Result);
Console.ReadLine();
}
}
Output:
Fig 5.0 we can see two countries delegate communicating with each
other.
}
}
So by this we can conclude that basically delegates are generally used for
communication between two parties i.e. Callbacks and Callbacks.
Enums
Enums are basically strongly typed constants.
If the programs contains set of integral values its better to replace them
with Enum, to make the program more readable and maintainable.
//Status 1:OrderedPlaced
//Status 2:OrderAccepted
//Status 3:Billed
//Status 4:TripCreated
//Status 5:Delivered
//Status 6:Cancelled
public int Status { get; set; }
Let take an example when we Order Details to be shared to the User let try
the same:
class Program
{
static void Main(string[] args)
{
//These will retrieved from database and we will print the details to the User that is
present in this array
//Status field is needed to be shown in String
}
}
}
}
case 1:
return
case 2:
return
case 3:
return
case 4:
return
case 5:
return
case 6:
return
default:
return
"Ordered Placed";
"Order Accepted";
"Billed";
"Trip Created";
"Delivered";
"Cancelled";
"Wrong Status";
By default they start with 0 and the value of each successive enum is
increased by 1 however you can specify the same as per your need.
Problem solving:
//enum declartion
public enum Status
{
//numbers denote what status in database mean
OrderedPlaced = 1,
OrderAccepted = 2,
Billed = 3,
TripCreated = 4,
Delivered = 5,
Cancelled = 6
};
public class OrderMaster
{
public int OrderId { get; set; }
public string OrderCreatedby { get; set; }
public long MobileNo { get; set; }
//declaring status of type enum Status
public Status status{ get; set; }
class Program
{
static void Main(string[] args)
{
//These will retrieved from database and we will print the details to the
that is present in this array
//Status field is needed to be shown in String
//as discussed enum is strongly typed constant so cast is required
OrderMaster[] order = new OrderMaster[3];
order[0] = new OrderMaster
{
OrderCreatedby = "Saillesh Pawar",
MobileNo = 999999999,
OrderId = 001,
//type casting to enum
status = (Status)1
};
order[1] = new OrderMaster
{
OrderCreatedby = "Virender Pawar",
MobileNo = 999999992,
OrderId = 003,
//type casting to enum
status = (Status)2
};
order[2] = new OrderMaster
{
OrderCreatedby = "Rakesh Pawar",
MobileNo = 99999993,
OrderId = 004,
//type casting to enum
status = (Status)5
};
User
case Status.OrderedPlaced:
return "Ordered Placed";
case Status.OrderAccepted:
return "Order Accepted";
case Status.Billed:
return "Billed";
case Status.TripCreated:
return "Trip Created";
case Status.Delivered:
return "Delivered";
case Status.Cancelled:
return "Cancelled";
default:
return "Wrong Status";
}
}
Now once we run our program we will find the same output as before but we
can see our code is better readable, understandable and easy to maintain if
any changes are done.
Fig 11.0: Difference between case without enum and with enum,
enum seems to be more readable as compared to without Enum.
Attributes
Attributes are nothing just declarative information which you can attached to
your program (i.e. class, property, method) and we can act on it. Attribute is
a class which inherits from system.Attribute class. It is denoted by [] square
brackets tag.
namespace Attributes
{
public class Customer
{
[Key]
public int CustomerID { get; set; }
public string CustomerName { get; set; }
public string CustomerAddress { get; set; }
}
}
DAL Class
namespace Attributes
{
public class DAL:DbContext
{
//collection of entitites that can be queried from the db
public DbSet<Customer> customer { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
So now when user inserts his details the Customer details is saved into DB.
Here
class Program
{
static void Main(string[] args)
{
//create a Customer object
Customer obj = new Customer();
Console.WriteLine("Enter the UserName");
//set the properties
obj.CustomerName = Console.ReadLine();
Console.WriteLine("Enter the Address");
obj.CustomerAddress = Console.ReadLine();
obj.addEmp(obj);
Console.ReadLine();
}
}
Now as the User Inserts his details the record is saved into the db. As shown
below:
Lets assume now we want to insert the list of Customer rather than single
customer so now we create a new method to insert the list of Customers as
shown below:
class Program
{
static void Main(string[] args)
{
//create a list Customer object
List<Customer> objCustList = new List<Customer>();
Console.WriteLine("Enter the list of customers to be added");
//will contain number of customer to be added
int range =Convert.ToInt32(Console.ReadLine());
//for loop till the range is exceeded
for(int i=0;i<range;i++)
{
//create a customer object
Customer customer = new Customer();
Console.WriteLine("Enter the UserName");
//set the properties
customer.CustomerName = Console.ReadLine();
Console.WriteLine("Enter the Address");
customer.CustomerAddress = Console.ReadLine();
//add customer object to the list of Customer
objCustList.Add(customer);
}
Customer.addEmpList(objCustList);
Console.ReadLine();
}
Now run the program and we will see the following output, as shown below:
Fig 13.0 Records after trying new method for adding list of
Customers to the db.
[Obsolete]
public static void addEmp(Customer cust)
{
//data access layer object
DAL dal = new DAL();
//adding a customer to
dal.customer.Add(cust);
//commiting changes into db
dal.SaveChanges();
//printing the value of the Id generated
Console.WriteLine("The Customer has been successfully stored in Db with id
"+cust.CustomerID);
}
Now if I try to call this method we can see the message is deprecated.
If we try to use it still, it will show a warning. What if we want to restrict the
User from using and want to send him alternative workarounds for this
method?
There are three overloaded attribute of Obsolete as shown above. Let see
the same:
public ObsoleteAttribute()//default obsolete
public ObsoleteAttribute(string message); //displaying user defined
message alternative workarounds.
public ObsoleteAttribute(string message, bool error);
error:
//
The Boolean value that indicates whether the obsolete element
usage is considered
//
an error.
Now if the user tries to call the addEmp method he will see a message
denoting ("Use only addEmpList method as shown below:
Fig 18.0 Not allowing the developer if he/she tries to use the
obsolete function.
Generics
}
}
What if we want to do the same for String values i.e. we need to create
the same method which accepts string as parameter as shown below:
class Program
{
static void Main(string[] args)
{
//calling static method of CompareClass and passing two string parameters
bool result = CompareClass.Compare("saillesh", "saillesh");
Console.WriteLine($"The result of the compare method is {result}");
ReadLine();
}
}
public class CompareClass
{
//compare method will take two string as a parameter and will return bool value true or false
public static bool Compare(string str1,string str2)
{
return str1 == str2;
}
}
class Program
{
static void Main(string[] args)
{
//calling static method of CompareClass and passing two object type parameters
bool result = CompareClass.Compare("saillesh", 1);
Console.WriteLine($"The result of the compare method is {result}");
ReadLine();
}
}
public class CompareClass
{
//compare method will take two int as a parameter and will return bool value true or false
public static bool Compare(object str1,object str2)
{
return str1 == str2;
}
}
We may however be able to compare the object types but its seems
foolish to allow numbers and string compared to each other as we did
above, Apart from that we are performing boxing and unboxing which
may results in poor performance because when a value typed is boxed
it is created a new object which takes a long time as compared to
simple reference.
So in order to avoid boxing and unboxing, In order to take the strongly
typed data type Generics comes into picture which can delay the
declaration of data type to be strongly typed in our class or method
until its called by the client(or during the runtime).
Declaration of using a Generic type in C#
public static bool Compare<T>(T str1,T str2)
If we try to use define the int type data type and try to pass
string in one parameter we face compile time error.
//calling static method of CompareClass and passing two object type parameters
bool result = CompareClass<int>.Compare(1, 2);
Console.WriteLine($"The result of the int compare method is {result}");
result = CompareClass<string>.Compare("Saillesh","Pawar");
Console.WriteLine($"The result of the string compare method is {result}");
ReadLine();
So here we learn how we can decouple our logic from the data type with the
help of Generic.