Showing posts with label .NET Languages. Show all posts
Showing posts with label .NET Languages. Show all posts

Saturday, March 10, 2012

Polymorphism via Interfaces

In previous post we discussed polymorphism via abstraction. Today, we will discuss polymorphism via interfaces. The concept is similar except that here you declare an interface with a signature which you will then implement in one or more derived class

Consider a base employee interface with signature and then you create a full time and part time employee classes that inherit from this interface.

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

namespace Polymorphism
{
    interface iEmployee
    {
        
        void PrintEmployee();
        
    }
}


Derived Class 1

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

namespace Polymorphism
{
    class FullTime : iEmployee
    {
        public int employeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays { get; set; }

        // a method signature declared in interface is implemented here
        void iEmployee.PrintEmployee()           {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}",
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
    }
}


Derived Class 2

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

namespace Polymorphism
{
     class PartTime:iEmployee
    {
        public int employeeID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string EmployeeType { get; set; }
        public string OverTime { get; set; }
        public string VacationDays {get;set;}
  
       // a method signature declared in interface is implemented here
        void iEmployee.PrintEmployee() 
        {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }
      public void Print()
        {
            Console.WriteLine("Employee Type={0}, OverTime={1}, VacationDays{2}", 
                              EmployeeType, OverTime, VacationDays);
            Console.WriteLine(Environment.NewLine);
        }

    }
}



As you can see, a method signature "PrintEmployee" is implemented in derived classes. A class can implement one or more interfaces and must implement the method signatures declared in each interface.

You can use the above classes as follows. Notice since the method PrintEmployee is declared in an interface, you cannot use it like you would if it was declared in a class. Since both PartTime and FullTime implement iEmployee, you should be able to cast the classes to iEmployee and then call PrintEmployee method.

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

namespace Polymorphism
{
    class Program
    {
        static void Main(string[] args)
        {
            PartTime Emp1 = new PartTime();
            //notice this property is declared in base class but available in derived class.
            Emp1.employeeID = 1234;
            Emp1.FirstName = "Part Time";
            //notice this property is declared in base class but available in derived class.
            Emp1.LastName = "Employee";
            Emp1.EmployeeType = "Part Time";

            iEmployee Emp = Emp1;
            Emp.PrintEmployee();

            FullTime Emp2 = new FullTime();
            //notice this property is declared in base class but available in derived class.
            Emp2.employeeID = 5678;
            Emp2.FirstName = "Full Time";
            //notice this property is declared in base class but available in derived class.
            Emp2.LastName = "Employee";
            Emp2.EmployeeType = "Full Time";

            Emp = Emp2;
            Emp.PrintEmployee();

            Console.ReadLine();
        }
    }
}

This is a basic concept but interfaces could be confusing. Hope this helps you understand the concept.

Thank you.



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.

Sunday, February 26, 2012

Arrays and Arraylist in .NET

So far we have been discussing the fundamentals of object oriented programming, difference between interfaces, abstract classes, enumerations, structures etc. Today, we will talk about using arrays and arraylists to store various objects and difference between the two.

Both arrays and arraylists are stored on a heap. Even if you store value types in an array or an arraylist, the values are implicitly converted to reference types (boxing) and you must explicitly convert them back to proper value types (unboxing) when using them.

Since the items stored in an array or an array list are objects, you can use them to also store reference to objects. For example,

consider the following class...

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

namespace ConsoleApp1
{
    class Student
    {
      
     private string _name;
     private string _address;
     private int _studentID;
     public string Name
     {
          get {return _name;}
          set {_name=value;}
     }
     public string Address
     {
          get {return _address;}
          set {_address=value;}
     }
     public int StudentID
     {
          get {return _studentID;}
          set {_studentID=value;}
     }
  }
    
}

Now let's use an array to store several references of these objects.

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            //Using an Array
 
            //first instance
             Student student1 = new Student();
             student1.Name = "Student One";
             student1.Address = "123, Peachtree Road, Atlanta, GA 30303";
             student1.StudentID = 1;
            //second instance
             Student student2 = new Student();
             student2.Name = "Student Two";
             student2.Address = "456, Peachtree Road, Atlanta, GA 30303";
             student2.StudentID = 2;
            //third instance
             Student student3 = new Student();
             student3.Name = "Student Three";
             student3.Address = "678, Peachtree Road, Atlanta, GA 30303";
             student3.StudentID = 3;

             //instantiate an array to store these objects.
             Student[] StudentsList = new Student[2];
             StudentsList[0] = student1;
             StudentsList[1] = student2;
             StudentsList[2] = student3;

            //since array is already of type Student, no typecasting is necessary.
            Console.WriteLine(StudentsList[0]);

       }
    }
}

There are several problems with this approach. First, you have to initialize an array and specify its size. Which means you have to know how many objects you are going to store in an array beforehand. Second limitation is that an array must be specific to the type you are going to store, meaning you cannot store two different types of objects in an array. Also, once an array has been initialized to a specific size, you cannot resize it downwards.

Now let's consider the same example using an arraylist.

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
             
            //first instance
             Student student1 = new Student();
             student1.Name = "Student One";
             student1.Address = "123, Peachtree Road, Atlanta, GA 30303";
             student1.StudentID = 1;
            //second instance
             Student student2 = new Student();
             student2.Name = "Student Two";
             student2.Address = "456, Peachtree Road, Atlanta, GA 30303";
             student2.StudentID = 2;
            //third instance
             Student student3 = new Student();
             student3.Name = "Student Three";
             student3.Address = "678, Peachtree Road, Atlanta, GA 30303";
             student3.StudentID = 3;

            //instantiate an arraylist to store these objects.
             ArrayList StudentList = new ArrayList();   
            
            // notice an arraylist isn't of a specifc type.
             StudentList.Add(student1);
             StudentList.Add(student2);
             StudentList.Add(student3);

            //since arraylist is a generic list, you must type cast it first.
            Console.WriteLine((Student)(StudentList[0]));

            //Arraylist allows for inserting an object at a specific position.

             //fourth instance
             Student student4 = new Student();
             student4.Name = "Student Four";
             student4.Address = "890, Peachtree Road, Atlanta, GA 30303";
             student4.StudentID = 4;
             StudentList.Insert(1, student4);

            //You can also remove an object from an array list
             StudentList.Remove(student4); // remove a specific object
            //OR
             StudentList.RemoveAt(2);   //remove whatever is at index 2
     
        }
    }
}

As you can see, an arraylist avoids some of the problems of an array. First, an arraylist doesn't have to be sized and resized. An element can be added or removed from an arraylist.

Note, since an arraylist isn't cast into a specific type during declaration, when reading the content from an arraylist, you must explicitly cast to a specific type, as show in the above code snippet.

An arraylist also allows for inserting an object at any position, including the position where an object may already exist. If you insert an element at a position already occupied by another element, the current element will simply push down.

Since an arraylist isn't of a particular type, you can add elements of reference or value types in an array, even mixing them.

For example you can do the following.

StudentList[0] = student1;
StudentList[1] = 5;
StudentList[2] = "This is a test";
StudentList[3] = student2;

But if you add objects of different types or value types in the same arraylist, you must first inspect the element to determine its type before casting it to the appropriate type. This is not only cumbersome and error prone, it also adds an unnecessary overhead.

To write out the content from the above example, you now have to do the following...

if (StudentList[1].GetType() == typeof(int))
   {
    //do something
   }

This becomes unusable pretty quickly. So, what should you do to get the flexibility of an arraylist without the added overhead? In the next post we will talk about generic collections and how they can aid us in a situation like this.

Friday, February 24, 2012

Structures in .NET

As we discussed in previous post, enumerations and structures are two complex types that are value types. Structures allow you encapsulate certain data elements similar to a class, except that structures are value types while classes are reference types.

Structures are very similar to classes with few differences.
  • Unlike classes, structures cannot inherit from other structures or a class, although they can implement interfaces.
    • Since they cannot inherit from other structures, an structure cannot be a base structure, which means structure members cannot be declared as "Protected".
  • Similar to classes, structures can have constructors, properties, methods etc.
  • Unlike classes, you cannot declare a parameterless constructor in a structure, although you can declare overloaded constructors with parameters. Strucutres always have a default constructor.
  • Unlike classes, you can instantiate an structure without using "new" operator.
Structures are suitable when you want to implement lightweight objects such as a point or color or a rectangle etc. 

Let's see an example in action...

    using System;
    struct StructExample
    {
        private int _width;
        private int _height;
   
        public int Width
        {
            get { return _width;}
            set {_width = value;}
         }

       public int Height
      {
           get { return _height;}
           set {_height = value;}
      }
   }


Let's use this structure

    Using System;
    class TestStructure
    {
       static void Main()
       {
             StructExample example1 = new StructExample();
             example1.Width  =1;
             example2.Height = 3;
             Console.WriteLine(example1.Width + ' ' + example1.Height);
             Console.Read();
        }
    }

As I mentioned previously, you should only use structures for lightweight objects because they are value types and are stored on a stack. Also, since they are not reference type, you are directly dealing with the structure and not with a reference, like you would with a class.

Thank you.








Wednesday, February 22, 2012

Enumerations

Recall my previous post about value types vs. reference types. Just to recap, simple data types such as int, float, double, decimal etc. are value types while complex types such as objects, strings are reference types. There are two exceptions to this concept. Structures and Enumerations. Despite being complex types, Structures and Enumerators are value types and hence they are stored on stack as opposed to heap.

In this post we will discuss enumerations and we will cover structures in next post.

Enumerations
Enumerations allow you to group constants at one place in a name-value pair format and allows you to access the values using strongly typed names. The key difference between an array list or a dictionary object and enumeration is that the arraylist / dictionary is a reference type and hence stored on heap while enumerators are value types and are stored on stack. Use of enumerators also allow you to keep the constants at one place hence being able to easily manage them and makes your code easier to read.

The underlying datatype for an enumeration can only be of an integral type. It can be of any integral type except "Char". The default type is int.

An enumeration is declared using enum keyword. Lets see an example.

enum Color
{
   Red,
   Blue,
   Green,
   Orange
}

If you don't specify the value, underlying integer datatype is assumed and the value is assigned from 0 onwards. For example in above example, Red=0, Blue=1, Green=2, Orange=3.

You can explicitly assign any value to each type, for example

enum Color
{
   Red = 8,
   Blue = 9,
   Green  =12,
   Orange=20
}


As I mentioned previously, underlying datatype for an enum can be any integral type except char. Following datatypes are supported 
  • byte, sbyte, short, ushort, int, uint, long or ulong.
To use any other datatype except int, declare it as follows...


enum Color : byte
{
   Red ,
   Blue ,
   Green ,
   Orange
}

Usage
Apart from keeping the constants at one place, it also makes code easier to read. See the following example...

 public class EnumTest
 {
   static void Main()
   {
      Console.WriteLine("Red={0}", Color.Red);
      Console.WriteLine("Blue={0}", Color.Blue);
   }
}

That's all there is to it. It is a relatively simple concept but when used appropriately promotes cleaner and readable code.

Thank you.

Wednesday, February 15, 2012

Boxing and Unboxing

In previous post we discussed the concept of value types vs. reference types and how two are different. Today we will discuss Boxing and Unboxing.

Boxing and Unboxing
Boxing is the process of converting a value type to a reference type. If you recall from my previous post about Value Types vs. Reference Types, the value types are stored on a stack while the reference types are stored on heap and a pointer to the reference type is stored on the stack.

Let's assume you have the following method..


public void Add(object obj, object obj2)
        {
            if (obj.GetType()  == typeof(string) && obj2.GetType() == typeof(string))
                {
                //do something...
                }
            else if (obj.GetType() == typeof(int) && obj2.GetType() ==typeof(int))
                {
                //do something...
                }
        }

 
When you call this method and pass an integer or some other value type variable, it is first boxed, i.e. converted to a reference type and then it is unboxed i.e. converted back to value type before it is used. Boxing is implicit but unboxing is explicit i.e. you must cast the boxed variable back into the value type before you can use it.

Note: The code above is for illustration only and you should try to avoid boxing/unboxing for obvious performance reasons.

Another example of implicit boxing is in the use of an arraylist. For example,

ArrayList list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);

Recall that an arraylist is a reference type. When you add an integer to the arraylist, it is then boxed i.e. converted to a reference type and then added to the arraylist. When you need to use the value assigned to this arraylist, it must be unboxed.

int i = (int)(list(0);



Tuesday, February 14, 2012

Value Types Vs Reference Types in .NET


Before we dive into the value types or reference types definition, let's take a step back and understand what happens when you declare a variable .NET.

Anytime you declare a variable, some memory is allocated to this variable. There are three pieces of information that is stored in memory - the variable name, its datatype and the value it contains. The variable is stored on one of the two types of memory - Stack and Heap.

When you declare a variable which is of value type (I know I am jumping ahead), some memory is allocated. When you declare another variable of the value type, another chunk of memory is allocated which is stacked on top of the first allocation and so forth. Think of stacks as just boxes stacked on top of one another. For value types the memory is allocated statically. For example, 4 bytes of memory is allocated to a variable of type Int.

Memory is allocated on a first come first serve basis but it is de-allocated in the reverse order i.e. Last In First Out (LIFO). Think of it as you are stacking boxes on top of each other and to remove them, you have to remove the last one first and so on.

When you create a variable of type reference, the object itself is allocated on another type of memory called "Heap". Just as the name suggests, heap is just a collection of reference type variables (also commonly called objects) and there is no particular order. A pointer to these reference type variables is stored on stack.

Memory De-Allocation
When you exit a method or a class where you instantiated and consumed these variables, memory is de-allocated in the following fashion

  • Stack is cleared first in LIFO order.
  • Heap is not cleared - Garbage Collector will clear it at some point
You may be wondering why value types are stored on stack and reference types are stored on heap?

The reason primarily has to do with the complexity. Value types are primitive data types such as Integer, Byte, SByte etc. and framework knows in advance how much memory to allocate when they are initialized. Reference types such as objects on the other hand are complex types. An object may have an instance of another object etc. which means the memory must be dynamically allocated, hence they are stored on a heap.

Another point to note is that all variables must be declared and instantiated, but .NET framework automatically instantiates the value types.

For example - 
int i = new int(5);  
can also be declared as int i = 5;

All reference types with the exception of String must be explicitly instantiated (unless your classes are declared as static/shared).

For example
Person clsPerson = new Person();

Value Types
  • All Numeric Data Types 
    • E.g. integer, byte, sbyte, short, Decimal, Double etc.
  • Variables of type Boolean, Char and Date
  • Enumerations
    • Since the underlying types for enumerators can only be of value type.
  • Structs / Structures
Reference Types
  • String
  • Arrays (even if their elements are value types)
  • Classes / Forms.
  • Delegates

In the future post we will discuss the concept of boxing and unboxing and the difference between structures and classes and performance impacts of using one over the other.

Thank you and as always, your comments are welcome!




Sunday, February 12, 2012

C# or VB.NET -- aah the choices!

All Programming Fundamentals! Although there are many other supported languages in .NET Framework, when it comes to .NET development though, most applications are developed in either C# or VB.NET. I know, I know there is F# and what not. But the focus of this post and most of my other blogs would be on these two languages.

Gone are the days when C# was significantly better than VB.NET in terms of features etc. so most of the differences that remain now are superficial as well as preferential.

Still, I wanted to put down some of my thoughts as well as some of the arguments I have heard from either side.

So, which one is better? Well it depends on two factors...

  • Your own Experience / Preference.
  • Market Conditions.
For some reason, perhaps due to old VB 6 hangovers, C# developers are more in demand than VB.NET developers and I have seen more jobs in C# than VB.NET. Now, it may not be true in all markets but at least it is true on my side of the pond.

Still, there are a few subtle differences between the two and I will summarize them below, at least for the water cooler conversation, if nothing else. Note, there are syntantical differences like any language and we are not discussing them here.

  1. I don't know about you but I find it easier to read VB.NET code than C# code, due to its "English" like syntax. One developer once told me - "I don't understand why do I need to put a ; (semicolon) at the end of each line in C#."

  2. Line Continuation - If you want to continue one line into next, in VB.NET you have to do something like & _ while in C# you don't need to do anything. Just don't type ; (that's the answer I gave to the developer who asked me above question BTW). Although, in VB 2010 there is an implicit line continuation and you don't have to use _ anymore, but frankly if you are using VB.NET, I rather see  _.

  3. Previous versions of C# didn't support optional parameters to a method while VB.NET always did. Although latest C# release now supports optional parameters.

  4. Keywords in VB.NET are more self explanatory than C # (this goes to my #1 comment above). For example, to allow a method to be overridden in a derived class, you add a keyword "Overridable" to the method in VB.NET in the base class. In C#, you use keyword "Virtual" instead - not so intuitive, is it?

  5. Similarly if you don't want your method to be overriden, you use keyword "NotOverridable" in VB.NET but there is no such thing as "NotVirtual" in C#. Instead it is "Sealed".

  6. "With.... End With" in VB.NET has no equivalent in C#.NET.

  7. I personally feel that VB.NET IDE in Visual Studio has better intellisense than C# IDE.

  8. C# on the other hand is less forgiving if you make a mistake. For example, unless you have Option Strict ON, you can get away with converting a value type to a reference type or a string to an int etc. without typecasting it, which may impact the performance of your application or worst may result in run-time errors. C# will not let you convert one variable type to another without typecasting.

  9. If you have Option Explicit OFF, you can consume variables without declaring them in VB.NET, no such luck in C#.

  10. VB.NET is not case sensitive but C# is. I find that extremely annoying in VB.NET because I feel it is a poor coding practice to declare variable in one case and use it in another.

  11. VB.NET has much easier event handling. You can simply declare an event and raise it without having to implement any delegates. In C#, you have to use delegates.

  12. I find it much easier to read comments in C#. You use // to start the comment while ' in VB.NET. I like C# comment feature so much that even in VB.NET I use '// .

  13. It is much easier to port your skills from C# to Java or PHP as their syntaxes are somewhat similar. On the other hand VB syntax allows you to venture into other tools with VB Scripting support. For Example, SSRS Reports (you can create custom code in SSRS RDLC with VB.NET).
This is not an exhaustive list but the most common ones that I remember. If you feel I missed any, let me know and I will be glad to add to the list.

Your comments are welcome!