Showing posts with label Instances.. Show all posts
Showing posts with label Instances.. Show all posts

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.

          

Monday, February 13, 2012

Difference between an Interface and an Abstract class

All Programming Fundamentals! It is rather easy to articulate the difference between the two, but I have seen people stumble when asked to explain it. So today, we will try to cover this topic and provide an example to clarify some of the key differences.

 Abstract Class
An Abstract Class is just like any other class with a few key differences. As we discussed in my previous post, non-static classes can be instantiated except with one type of class - an Abstract Class. In other words, an abstract class is one that cannot be instantiated and can only be used as a parent class in other derived (concrete) classes. Since this class cannot be instantiated and you cannot use a non-static class without instantiating it, you cannot use the abstract class by itself. You must inherit from it in other class(es) to use it.

An abstract class may have one or more methods that are completely implemented but it must have at least one abstract method that must be implemented in the derived class(es). This is what makes the abstract class - abstract.

So, in a nutshell an abstract class is just like any other class except that it cannot be instantiated and must have one or more abstract (unimplemented) methods.

Interface
An Interface is not a class. It is a contract and all classes that implement the interface must implement all the properties/methods declared in an Interface.

Unlike an abstract class, an interface cannot have actual implementation of any property/method and also all the properties / methods must be declared public.

Since an interface cannot have any implementation, all the classes inheriting this interface must implement all the methods defined in the interface. Abstract class on the other hand can have fully implemented methods and derived classes can simply use that implementation.

If an abstract class has all the methods defined as abstracts, then both Interface and Abstract class is the same.

Why would you use one over the other?

Both interfaces and abstract classes are good if you want to keep the same structure in your classes inheriting from it. But abstract class allows you to implement one or more common method that can be used as is by all the classes. One advantage that interface have over abstract class is that at least in C# and VB.NET (also true in Java but not in C++) a class can only inherit from one class, while it can implement multiple interfaces.

Interfaces are generally used to define the abilities of a class i.e. what a class can do. For example - IComparable interface. This interface defines "Compare To" signature which can be implemented in the class to compare the instance of an object with another object of the same type. Any class that implements IComparable interface must be capable of doing so.

Abstract classes on the other hand generally implement or define the core capability of the class. For example a MemoryStream class can inherit from a Stream abstract class that implements a Serialize method to serialize the content.

You generally want to use interface if various classes only share certain features, although they may be of different type. For example, a class called Car and a class called Plane may implement the same IMovable interface. You want to use an abstract class when both classes are of same or similar kind. For example a class "BMW" and a class "Lexus" can inherit from the same abstract class called "Car".

If you modify an interface and add a new method, you must modify all the classes implementing that interface to implement that method. You can however modify an abstract class and as long as you fully implement a new method, you don't have to touch other classes inheriting from it.

Let's see both Interface and Abstract class in action.

Abstract Class

Using System;
namespace AbstractInterface
{
    public abstract class Student  
           // notice keyword abstract. In VB.NET the equivalent keyword is MustInherit
     { 
        protected string studentnum;     //protected variables
        protected string studentname;


      public abstract String StudentNumber 
              // notice the keyword abstract. The property is not fully implemented.
           {
             get;
             set;
           }
      public abstract String StudentName
        {
           get;
           set;
        }
     public String GetStudentInfo() // notice this method is fully implemented
      {
        return "Student Number: " + studentnum + " Name: " + studentname;
      }
     public abstract String EnrollmentStatus(); // notice this method is not implemented.


    }
}
   
Concrete Class


using system;
namespace AbstractInterface
{
    public class GraduateStudent : Student // this class inherits from Student class.
   {
     public GraduateStudent()   //constructor
      {
       }
      public override String StudentNumber
           // remember abstract class didn't implement this property so we have to implement it here.
           //   Notice keyword override
        {
           get
            {
               return studentnum;
            }
            set
            {
               studentnum = value;
            }
        }
        public override String StudentName
         
        {
           get
            {
               return studentname;
            }
            set
            {
               studentname = value;
            }
        }


      public new String GetStudentInfo() // this method is implemented in base class.
      {
        return base.GetStudentInfo();
      }


    }
    public override String  EnrollmentStatus () // notice this method is not implemented in base class


      {
        return studentname + " is enrolled."
      }


    }
}

Now lets see an Interface Example

Interface


Public interface IStudent // As a convention, interfaces are prefixed with "I"
{


 String StudentNumber
              // No need to specific "public" since interface can only have public properties/methods.
           {
             get;
             set;
           }
      String StudentName
        {
           get;
           set;
        }
     String GetStudentInfo();
     
     String EnrollmentStatus();
   
          // notice no implementation of any method or property
   }

Concrete Class using Interface


using system;
namespace AbstractInterface
{
     public class Student2 : IStudent    // implements interface


      protected string studentnum;     //protected variables
      protected string studentname;


     public  Student2  ()   //constructor
        {
        }
      public String StudentNumber
           // must be implemented here, otherwise compiler will throw error.
         
        {
           get
            {
               return studentnum;
            }
            set
            {
               studentnum = value;
            }
        }
        public String StudentName
       
        {
           get
            {
               return studentname;
            }
            set
            {
               studentname = value;
            }
        }


      public String GetStudentInfo() // implemented here
      {
        return "Student Number: " + studentnum + " Name: " + studentname;
      }


    }
    public String  EnrollmentStatus ()


      {
        return studentname + " is enrolled."
      }


   // notice - all properties and methods declared in interface must be implemented. Every class inheriting       //from this interface must implement all of them.


    }


}

Hopefully this will help clarify some of the differences between an Interface and an Abstract class. As always, your comments are welcome.

Wednesday, February 8, 2012

Classes and Objects in Object Oriented Programming

All Programming Fundamentals! In my previous post, I wrote about four principles of Object Oriented Programming. Today, we will take it one step further and discuss the concept of a Class and an Object. We will also discuss types of classes.

Class is a template that exhibit certain characteristics. For example, blueprint of a house defines the number of rooms, doors, room size etc. You can use this blueprint to build one or more houses. Similarly, class is a blueprint that can be used to build objects. Each class must have a name, one or more attributes or properties, one or more methods that can be used to perform operations on the object(s) created from this class. For example, A class called "Student" may have the following format.

Class Name
Properties
Methods

An object is an instance of the class. In your application, you can declare an instance of the class and assign it to a variable which will then allow you to access the public properties to read or set the values and use the public methods to perform operations. 

We will talk more about the Public vs. Private vs. Protected Properties/Methods in future post, but for now just remember that any object can access public methods and properties of another object (there are some caveats to it, such as they must be in the same assembly or the consuming object's assembly must reference the assembly where the object resides and they must be imported in the class either by Imports or Using statement on top of the class - more on that later).

Some classes don't need to be instantiated before they can be used. Their public methods and properties are always available without having to instantiate and create an object. I guess you could say that your application automatically creates an instance of the class for all other classes to use.

Remember, while you can have many instances of the class that can be instantiated and one instance will not share the other instance. For example, you can have two instances (objects) of "Student" class called "Student 1" and "Student 2". The properties of "Student 1" will be different than that of "Student 2". Classes that can't be instantiated by definition only have one instance hence only one set of properties.

In C#,  a class declared with STATIC keyword cannot be instantiated. In VB.NET, you don't have a shared class per se, but a Module is closest to the static class. 

In a static class, all methods must be declared static. However a non-static class can have both static and non-static members. Static members will be available regardless of whether the class is instantiated and only one copy of static member will exist, while there can be multiple instances of non-static members. In VB.NET, you can declare methods with keyword SHARED  which will have the same behavior as STATIC in C#.

Constructors
Constructors allows non-static classes to be instantiated. In VB.NET, the constructor is declared as a Public Sub New. In C#, the constructor is same name as the class name. You can have more than one constructor per class. (See example below)


Example:

C#
using System;
namespace 6thGrade
{
public class Student
{
   private int _age;
   private string _name;

   // Default constructor:
   public Student() 
   {
      _name = "N/A";    // assigning a value "N/A" to private string variable name.
   }

   // Another Constructor:
   public Student(string name, int age) 
   {
      this._name = name; // assigning a value passed to the constructor to variable name.
      this._age = age;  // assigning a value passed to the constructor to variable age.
   }

   // Printing method:
   public void PrintStudent() 
   {
      Console.WriteLine("{0}, {1} years old.", name, age);
   }
}
}

VB.NET

Imports System
Namespace 6thGrade
Public Class Student

     Private _age As Int32
     Private _name As String

    Public Sub New()     // default constructor
          name="N/A"
    End Sub
    
    Public Sub New(ByVal name As String, ByVal age As Int32)
          _name=name
          _age=age
    End Sub
    
    Public Sub PrintStudent()
       Console.Writeline(name + ", " + age)
    End Sub
End Class
End Namespace

STATIC CLASS 

C#
using System;
namespace 6thGrade
{
public static class Student
{
   private int _age;
   private string _name;

  //static method
public static void studentinfo(string name, int age)
{
_name=name;
_age = age;
}

   // Printing method:
   public static void PrintStudent() 
   {
      Console.WriteLine("{0}, {1} years old.", name, age);
   }
}
}

VB.NET

Imports System
Namespace 6thGrade
Public Class Student                          // No Static equivalent in VB.NET

     Private _age As Int32
     Private _name As String

    Public Sub New()     // default constructor
          name="N/A"
    End Sub
    
Public Shared Sub studentinfo(ByVal name As String, ByVal age As Int32)
{
_name=name
_age = age
}
Public Shared Sub PrintStudent()
       Console.Writeline(name + ", " + age)
    End Sub
End Class
End Namespace

We will talk more about classes and associations, compositions, property/method accessibility etc in subsequent posts.

Thank you and as always, your comments are welcome!