Showing posts with label Scalable Applications. Show all posts
Showing posts with label Scalable Applications. Show all posts

Thursday, March 1, 2012

C# Delegates

The concept of delegates is somewhat confusing and developers often wonder why we need them and where would we use delegates? We will discuss delegates with an example and hopefully clarify potential uses for them.

Consider a list object of a specific type. You can encapsulate one or more objects of the same type in this list and pass the list to other methods to read and do something with those objects. Delegates are similar in nature except that they encapsulate references to the methods of an object.

A delegate can encapsulate any method as long as method signatures are same as those of delegates. Use can then pass around those delegates or use them just as you would use the method encapsulated in those delegates.

Let's consider an example.

In this example, we will create a class which will take the hourly pay, hours worked, tax rate and return weekly pay as well as tax.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class CalculateWeeklyPay
    {
        private double _hourlypay;
        private double _hours;
        private double _overtimerate;
        private double _taxrate;

   public CalculateWeeklyPay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate;
        }
        public double calculateTax()
        {
            double grosspay = calculateGrossPay();
            double tax = grosspay * ((double)_taxrate / 100);
            return tax;
        }
  public double calculatePay(double hourlypay, double hours, 
                             double overtime, double taxrate)
        {
            _hourlypay = hourlypay;
            _hours = hours;
            _overtimerate = overtime;
            _taxrate = taxrate; 
            return calculatepay();
        }
        public double calculatePay()
        {
            return calculatepay();
         }
        private double calculatepay()
        {
            double grosspay = calculateGrossPay();
            double netpay = grosspay-(grosspay * ((double)_taxrate / 100));
            return netpay;
        }
        private double calculateGrossPay()
        {
            double basepay;
            double overtimepay = 0;
            double grosspay;
            
            if (_hours > 40)
            {
                overtimepay = (_hours - 40) * (_hourlypay * _overtimerate);
                basepay = 40 * _hourlypay;
            }
            else
            {
                basepay = _hours * _hourlypay;
            }
            grosspay = basepay + overtimepay;
            return grosspay;
        }
     }
}

Now, lets create a console app, which will instantiate this object and then return the weekly pay and tax. We will create two delegates. One delegate will work with two methods (CalculatePay and CalculateTax) and another delegate will work with overloaded CalculatePay method.

Note, a delegate must have the same signature and same return type of the referenced method that it will encapsulate.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        //declared two deletages, one for each method
        //(since they have different signatures, you can't use same delegate)
        //also note return type for the delegate 
        //must be same as the return type of the signature.
        public delegate double delegate1();
        public delegate double delegate2(double hourlypay, double hours, 
                                         double overtime, double taxrate);
      
           
        static void Main(string[] args)
        {
            double hourlyPay = 7.50;
            double hours = 45;
            double overtimeRate = 1.5;
            double taxRate = 5;
          CalculateWeeklyPay calculatepay = new CalculateWeeklyPay(hourlyPay, 
                                                 hours, overtimeRate, taxRate);
            //you must instantiate a delegate
            delegate1 firstDelegate = new delegate1(calculatepay.calculatePay);
            Console.WriteLine("First Delegate {0} ", firstDelegate());
            Console.WriteLine(Environment.NewLine);
            //you can use same delegate for another method as long as 
            //its signatures and return type are same
            delegate1 anotherDelegate = new delegate1(calculatepay.calculateTax);
            Console.WriteLine("First Delegate Different Use {0} ", 
                              anotherDelegate());
            Console.WriteLine(Environment.NewLine);
            //let's use second delegate
            delegate2 secondDelegate = new delegate2(calculatepay.calculatePay);
            //you must pass the parameters that this delegate is expecting, 
            //otherwise a runtime error will occur
            Console.WriteLine("Second Delegate{0} ", 
                       secondDelegate(hourlyPay, hours, overtimeRate, taxRate));
            Console.WriteLine(Environment.NewLine);
            Console.Read();
        }
    }
}


One of the main use of delegates is in events. Suppose you want an object to notify another object when something happens. For example, a stock market object should fire an event when stock price changes for a stock you are watching. Another object (listener) can capture this event and do something with it instead of constantly polling the stock market object to see if the price has changed. In C#, you need delegates to create events such as this.

We will discuss events in future posts.

Thank you.

Tuesday, February 28, 2012

Generic Collections

In previous post we talked about Arrays and a special collection object called an ArrayList. We also saw some of the benefits and drawbacks of each approach. Today we will talk about generic collections and how you can use them to create a collection of a specific type and add objects of that particular type to this collection.

We will also talk about how you can pass a collection of any type to a generic method and then inspect the type and do something with it.

Generic Collections
Lets assume you have the following class...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GenericsTest
{
    public class Sales
    {
        private string _salesAssociate;
        private double _projected;
        private double _actual;

        public String SalesAssociate
        {
            get { return _salesAssociate; }
            set { _salesAssociate = value; }
        }
        public double Projected
        {
            get { return _projected; }
            set { _projected = value; }
        }
        public double Actual
        {
            get { return _actual; }
            set { _actual = value; }
        }
    }
}

Let's create another class...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace GenericsTest
{
    public class Salary
    {
        private string _salesAssociate;
        private double _baseSalary;
        private double _commission;

        public String SalesAssociate
        {
            get { return _salesAssociate; }
            set { _salesAssociate = value; }
        }
        public double BaseSalary
        {
            get { return _baseSalary; }
            set { _baseSalary = value; }
        }
        public double Commission
        {
            get { return _commission; }
            set { _commission= value; }
        }
    }
}

Let's build a collection of these objects. We will create two generic collections - each of specific type i.e. Sales and Salary. Notice, that since the collection is of specific type, you cannot mix and match the objects. Although there are ways to do that, but we will cover it in future posts.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace GenericsTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //declare generic list of type sales
            List<Sales> lstSales = new List<Sales>();
            List<Salary> lstSalary = new List<Salary>();

           //lets add few objects to these collections
            Sales oSales = new Sales();
            oSales.SalesAssociate = "Mike Smith";
            oSales.Projected = 1000;
            oSales.Actual = 1150;
            //Add to collection
           lstSales.Add(oSales);

           //add another object
            Sales oSales1 = new Sales();
            oSales1.SalesAssociate = "Patty Smith";
             oSales1.Projected = 1200;
            oSales1.Actual = 1350;
            //Add to collection
            lstSales.Add(oSales);

           //lets add few objects to another collection
            Salary oSalary = new Salary();
            oSalary.SalesAssociate = "Mike Smith";
            oSalary.BaseSalary= 500;
            oSalary.Commission= 200;
            //Add to collection
           lstSalary.Add(oSalary);

           //add another object
            Salary oSalary1 = new Salary();
            oSalary1.SalesAssociate = "Patty Smith";
            oSalary1.BaseSalary= 500;
            oSalary1.Commission= 275;
            //Add to collection
           lstSalary.Add(oSalary1);
    
       }
    }
}
          


What if you want to use the same method to pass these collections and do something based on its type. Since every object in .NET inherits from System.Object, you can pass them as object type, but instead we will do something better here.

Let's create yet another class which will do something with these two objects defined above.

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Web;

namespace GenericsTest
{
    public static class DataType
    {
        
        public void DoSomething<T>(List<T> lstData)
        {
           
        if (lstData.GetType() == typeof(List<Sales>))
         {

         for (int i = 0; i < lstData.Count; i++)
         {
        Sales oSale = (Sales)Convert.ChangeType(lstData[i], typeof(Sales));
        Console.WriteLine(String.Format("Sales Associate:{0},Projected Sales:{1},
        Actual Sales:{2}",oSale.SalesAssociate, oSale.Projected,oSale.Actual));                   
        Console.WriteLine(Environment.NewLine);            
         }
       }
       if (lstData.GetType() == typeof(List<Salary>))
       {

       for (int i = 0; i < lstData.Count; i++)
       {
        Salary oSalary = (Salary)Convert.ChangeType(lstData[i], typeof(Salary));
        Console.WriteLine(String.Format("Sales Associate:{0},Salary:{1},
        Commission:{2}",oSalary.SalesAssociate, 
        oSalary.BaseSalary,oSalary.Commission));              
        Console.WriteLine(Environment.NewLine);            
        }
       }
      }
    }
  }

Now all you have to do is pass either collection to this method. You can extend this method to accept collection of other types, like this...

DataType.DoSomething(lstSales);
//or
DataType.DoSomething(lstSalary);     


Generics is a very powerful concept which allows for better and more flexible code. Generics, along with reflection which we covered earlier can be a powerful tool.

Thank you.


Monday, February 20, 2012

Reflection in .NET

Reflection is the process of discovering classes, modules, assemblies or the type information of an object at run-time. Reflection works by extracting metadata information from an assembly and using this metadata to do something with it. System.Reflection namespace in .NET Framework provides the classes and interfaces that you can use to discover a class, instantiate it, discover its methods, properties and invoke them at run-time just like you would during compile time.


There are many uses of reflection, but let's demonstrate one potential use with an example.


Suppose for example, you have a sales application installed on sales associates laptops. This application allows sales associates to enter sales orders on their laptops, when they visit the clients. The application is run in offline mode but when the sales associate returns back to the office and connects to the network, the application will detect it and automatically uploads the sales orders in a centrally hosted database.


When a sales associate enters the information, a collection of the Orders object is serialized on sales associates laptop. When this laptop is connected to the company network, the application deserializes the Orders, uses reflection to type cast the object into the Orders Type and then calls the appropriate methods to save data in the database.


Let's illustrate this with an example.

//Create an Orders Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReflectionTest    
{
public class Orders
{
      private int _itemNumber;      
      private int _quantity;      
      private int _customerNumber;
      //properties
     
      public int ItemNumber
      { 
        get { return _itemNumber; }          
        set { _itemNumber = value; }      
      }
      public int Quantity          
      {
         get { return _quantity; }         
         set { _quantity = value; }      
      }
      public int CustomerNumber         
      {
         get { return _customerNumber; }         
         set { _customerNumber = value; }        
      }
      //constructor
     
      public Orders() 
      {}
     //Method to save data to the database
     
public void SaveToDB(List<Orders> orders)           
     {
       // do something here         
     }
  }
}

 Since we are going to serialize this object and save it on associate's laptop, let's write a class that is serializable and has a variable which stores the collection of Orders object (you can make it generic to allow for serializing and storing any object).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace  ReflectionTest 
{
    [
Serializable]    

    public class SaveObjectLocally    
    {
     //use generics so this class can be used to store any object types not just Orders
    private List<Orders> _collObjects = new List<Orders>();     

    private string _saveMethod;     
    private string _className;
    public SaveObjectLocally() { }     
    //properties
     public List<Orders> ObjectList
     {          
         get { return _collObjects; } 
         set { _collObjects = value; }     
     }
     public string SaveToDB
     {          
         get { return _saveMethod; }          
         set { _saveMethod = value; }     
     }
     public string ClassName          
     {
         get { return _className; }          
         set { _className = value; }     
     }
     //serialize
     public void Serialize(string filePath)
     {
         
Stream stream = File.Open(filePath, FileMode.Create);           

          BinaryFormatter bf = new BinaryFormatter();
          bf.Serialize(stream, this);
          stream.Close();     
     }
    //deserialize
      public SaveObjectLocally DeSerialize(string filePath)         
     {
        Stream stream = File.Open(filePath, FileMode.Open);         
        BinaryFormatter bf = new BinaryFormatter();         
        SaveObjectLocally SaveObject = (SaveObjectLocally)bf.Deserialize(stream);
        stream.Close();  
        return SaveObject; 
          }
 
    }
}

//Main Program

using System;

using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace  ReflectionTest 
{
    class Program 

    {
        
static void Main(string[] args) 
         {
              
Orders clientOrder = new Orders();
              clientOrder.ItemNumber=123;
              clientOrder.Quantity = 5;
              clientOrder.CustomerNumber=101;
              //lets assign this order to SaveObjectLocally and 

              //then save it on local machine           
             //create a list object
             
List<Orders> ordersList= new List<Orders>();
             ordersList.Add(clientOrder);
             SaveObjectLocally save = new SaveObjectLocally(); 
             save.SaveToDB = 
"SaveToDB"; 
             save.ObjectList = ordersList;


             //serialize

             save.Serialize(@"C:\Temp\Orders.xml");
                
           }
         //deserialize the saved object and upload.
         public static void UploadData() 
          {

          SaveObjectLocally save = new SaveObjectLocally(); 
          SaveObjectLocally retrieveObject = save.DeSerialize(@"C:\Temp\Orders.xml"); 
          string saveMethod = retrieveObject.SaveToDB;
          string className = retrieveObject.ClassName; 
          List<Orders> orders = retrieveObject.ObjectList;
          //now use reflection to instantiate the object
          Type ClassType = Type.GetType(className);          
          object obj = Activator.CreateInstance(ClassType);
          System.Reflection.MethodInfo callingMethod = ClassType.GetMethod(saveMethod);
          callingMethod.Invoke(obj,new Object[] {orders});
         }
         //If you have multiple objects serialized 

        //you can loop through all the files and upload one by one.
   }  
}

The example above is one use of Reflection where you can instantiate an object at run time and invoke its methods.

GetType.GetMethod and GetType.GetMethods() return you a single method or a list of methods.

Similarly, GetType.GetField() and GetType.GetFields() return you a single field or an array of all fields.

GetType.GetProperty() and GetType.GetProperties() returns property or a list of properties respectively.

You can also find out the parameters a method needs and also its return type. MethodInfo() provides information about the return type of a method and GetParameters() provides information about the parameters that a method expects.

GetConstructors() returns a list of constructors associated with this class.

Assembly Class
Assembly class is used to gather information about an assembly and manipulate the assembly. You can use it to load modules and assemblies at runtime and also search the type information within an assembly once it is loaded. Assembly class has the following methods


  • Load() - You can pass the assembly name as input parameter to search and load the assembly.
  • LoadFrom() - Takes the complete path of an assembly to search at a particular location.
  • GetExecutingAssembly() - Get the information about the currently running assembly.
  • GetTypes() - Allows you to obtain the details of all the types that are present in the assembly.
  • GetCustomAttributes() - Gets the list of custom attributes associated with this assembly. You can also pass a Type Object as a second parameter to this method to find the attributes of a specific type associated with this assembly.

As you can imagine, reflection is a very powerful feature that allows for late binding and flexibility otherwise not available during compile time. Hopefully this article will provide you enough pointers to try out reflection on your own and discover some of its additional powerful features.

Thank you and as always, your comments are welcome.

          

Saturday, February 18, 2012

Shallow Vs. Deep Copy


Although the concept is relatively simple, I have seen many developers struggle with the concept of shallow vs. deep copy.

First, both shallow and deep copy involves copying an object to another object. The difference lies in what is copied when the object contains a variable of reference type such as an instance of another object or an array / arraylist.

Shallow Copy
When you copy an object into another object, all the non-static members are copied from the original object to its copy. All the variables of value type are copied, but if the object contains variables of reference type, then only the reference is copied but the actual referred object is not copied. So, both the actual object and its copy refer the same instance of the object that is being referenced.

For example, consider the following class, which references another object

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace ShallowDeep
{
[Serializable]
public class Employee
{
    private string _name;
    private int _age;
    private Address _empAddress; // reference to another class, hence a reference type.
    public String Name
     {
        get { return _name; }
        set { _name = value; }
     }
    public int Age
     {
        get { return _age; }
        set { _age = value; }
     }
    public Address EmpAddress
     {
        get { return _empAddress; }
        set { _empAddress = value; }
     }
    //method to create a shallow copy
    public Employee CopyShallow(Employee EmpCopy)
       {
         //use MemberWiseClone to create a shallow copy
         return (Employee)EmpCopy.MemberwiseClone();
       }
    //Method to clear a deep copy
    public Employee CopyDeep(Employee EmpDeepCopy)
       {
          MemoryStream ms = new MemoryStream();
          BinaryFormatter bf = new BinaryFormatter();
          bf.Serialize(ms, EmpDeepCopy);
          ms.Seek(0, SeekOrigin.Begin);
          Employee result = (Employee)bf.Deserialize(ms);
          ms.Close();
          return result;
       }
   }
 
 }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShallowDeep
{
    public class Address
    {
        private String _mailingAddress;

        //constructor
        public Address(string MailingAddress)
        {
           _mailingAddress = MailingAddress;
        }
        public String EmpAddress
        {
            get{return _mailingAddress ;}
            set{ _mailingAddress =value;}
        }
     }
 }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ShallowDeep
{
class Program
{
    static void Main(string[] args)
    {
       //Shallow Copy
       //create an instance of Employee Class
       Employee oEmployee = new Employee();
       oEmployee.Name="Test User";
       oEmployee.Age = 30;
       Address oAddress = new Address("123 Ross Street, Atlanta, GA, 12345");
       oEmployee.EmpAddress=oAddress;
       //Now perform a shallow copy
       Employee oEmployee2 = oEmployee.CopyShallow(oEmployee);
      //Now lets do the following
      oEmployee2.Age = 25;
      oAddress.EmpAddress = "303 Peachtree Road, Atlanta, GA, 30032";
      //Check the value of oEmployee2.EmpAddress.
     int empOriginalAge = oEmployee.Age;
     int empCopyAge = oEmployee2.Age;
     Address EmpOriginalAddr = oEmployee.EmpAddress;
     Address EmpCopyAddr = oEmployee2.EmpAddress;
   }
  }
}


Notice the value of empOriginalAge=30 but the value of empCopyAge=25, but the value of EmpOriginalAddr and EmpCopyAddre is same i.e. "303 Peachtree Road, Atlanta, GA, 30032"


Deep Copy
To be able to deep copy an object, it must be serializable. Difference between a shallow and deep copy is that in addition to a bit by bit copy of a value object, deep copy also copies the reference object, instead of just copying only the reference to the object.

Let's use the same example as above, but instead use DeepCopy method.

Add the follow snippet to the method above.
//Deep Copy
//create an instance of Employee Class
Employee oEmployeeDeep = new Employee();
oEmployeeDeep.Name="Test User";
oEmployeeDeep.Age = 30;
Address oAddress2 = new Address("123 Ross Street, Atlanta, GA, 12345");
oEmployeeDeep.EmpAddress=oAddress2;
//Now perform a deep copy
Employee oEmployeeDeep2 = oEmployee.CopyDeep(oEmployeeDeep);
oEmployeeDeep2.Age = 25;
oAddress2.EmpAddress = "303 Peachtree Road, Atlanta, GA, 30032";
//Check the value of oEmployee2.EmpAddress.
Address EmpAddress = oEmployeeDeep2.EmpAddress;



The value of the EmpAddress will still be "123 Ross Street, Atlanta, GA, 12345".

Hope this helps clarify the difference between a shallow and deep copy. Remember, shallow sopy is done via MemberWiseClone(), while a deep copy is performed by serializing the object, hence the class must be serializable.

Just remember, the key difference is that in shallow copy only a reference to any reference type variable  is copied while in deep copy, the referenced object itself is copied.

Thank you and as always, your comments are appreciated.