Saturday, April 10, 2010

Generic:

Difference between Arraylist and Generic List

 
private void button1_Click

(object sender, EventArgs e)
{
//Arraylist - Arraylist accept values as object
//So i can give any type of data in to that.
//Here in this eg: an arraylist object accepting
//values like String,int,decimal, char and a custom object

Employee emp = new Employee("2", "Litson");
ArrayList arr = new ArrayList();
arr.Add("Sabu");
arr.Add(234);
arr.Add(45.236);
arr.Add(emp);
arr.Add('s');
//This process is known as boxing

//To get inserted vales from arraylist we have to specify the index.
//So it will return that values as object.
//we have to cast that value from object to its original type.

String name = (String)arr[0];
int num = (int)arr[1];
decimal dec = (decimal)arr[2];
Employee em = (Employee)arr[3];
char c = (char)arr[4];
//This process that is converting from object to its original type is known as unboxing
//------------------------------------------------------------------------------------
//Generic List
//List<>

//Main advantage of Generic List is we can specify the type of data we are going to insert in to
//List. So that we can avoid boxing and unboxing
//Eg:
List strLst = new List();
strLst.Add("Sabu");//Here List accepting values as String only
strLst.Add("Litson");
strLst.Add("Sabu");
strLst.Add("Sabu");

List intLst = new List();
intLst.Add(12);//Here List accepting values as int only
intLst.Add(14);
intLst.Add(89);
intLst.Add(34);

List decLst = new List();
decLst.Add(2.5M);//Here List accepting values as deciaml only
decLst.Add(14.4587m);
decLst.Add(89.258m);
decLst.Add(34.159m);

List empLst = new List();
empLst.Add(new Employee("1", "Sabu"));//Here List accepting Employee Objects only
empLst.Add(new Employee("2", "Mahesh"));
empLst.Add(new Employee("3", "Sajith"));
empLst.Add(new Employee("4", "Binu"));


//To get values from Generic List
String nme = strLst[0]; //No need of casting
int nm = intLst[0];
Decimal decVal = decLst[0];
Employee empVal = empLst[0];
}

A Fast-Track Overview to Generics



Overview

.Net framework 2.0 introduced Generics concept to make possible designing classes and methods to refer one or more types.
Generics provide the features like; Type safety, Performance, Effeciency, Code Maintenance, parameteric polymorphism. Etc.

Declaration




public class Test
{
public void Display()
{
// code
}
}



-----------------------------------------------------

Usage




Test test = new Test();
Test test = new Test();
Test test = new Test();





-----------------------------------------------------

Geberics Collection

These are several in-built collection types.
These are more type-safe and efficient then non-generic collection types.
These are recommended as they provide immediate type safety

Genaric Replaces for some existing collections

List : corresponds to ArrayList.
Dictionary : corresponds to Hashtable.
Queue : corresponds to Queue
Stact : corresponds to Stack
SortedList : corresponds to SortedList (based on the implementation of Icomparer

Newly introduced Generic Collection (no replecement for existing collection)

LinkedList
SortedDictionary : corresponds to Hashtable.
Queue : corresponds to Queue
Stact : corresponds to Stack

Examples

List (Generics based)




List list = new List();

list.Add(“item1”);
list.Add(“item2”);
list.Add(“item3”);

foreach (string s in list)
{
Console.WriteLine(s);
}





-----------------------------------------------------

Dictionary (Generics based)




Dictionary dictionary = new Dictionary();

dictionary.Add(“key1”, “item1”);
dictionary.Add(“key2”, “item2”);
dictionary.Add(“key3”, “item3”);

Console.WriteLine(dictionary(“key2”));

foreach (KeyValueCollection kvc in dictionary)
{
Console.WriteLine(“ Key = {0}, Value = {1} ”, kvc.Key, kvc.Value );
}

Dictionary.KeyCollection kc = dictionary.Keys;
Dictionary.ValueCollection vc = dictionary.Values;






-----------------------------------------------------

Queue (Generics based)




Queue queue = new Queue();

queue.Enqueue(“item1”);
queue.Enqueue(“item2”);
queue.Enqueue(“item3”);

foreach (string s in queue)
{
Console.WriteLine(s);
}

Console.WriteLine(“First element = {0} ”, queue.Peek()); // returns beginning element
Console.WriteLine(“First element = {0}, remove ”, queue.Dequeue()); // returns and remove beginning element
Console.WriteLine(“Contains = {0} ”, queue.Contains(“itsm3”)); // returns true false






-----------------------------------------------------

Stack (Generics based)




Stack stack = new Stack
stack.push(“item1”);
stack.push(“item2”);
stack.push(“item3”);
stack.push(“item4”);
stack.push(“item5”);

foreach (string s in stack)
{
Console.WriteLine(s);
}

boolean b = stack.Contains(“item3”); // true / false

Console.WriteLine(“First element = {0} ”, stack.peek()); // returns top object without removing it
Console.WriteLine(“First element = {0} with remove”, stack.pop()); // returns top object with removing it






-----------------------------------------------------

SortedList (Generics based)




SortedList sortedList = new SortedList();

sortedList.Add(“first, “First Item”);
sortedList.Add(“second”, “Second Item”);
sortedList.Add(“third”, “Third Item”);
sortedList.Add(“forth”, “Forth Item”);
sortedList.Add(“fifth”, “Fifth Item”);



-----------------------------------------------------

This has covered the Basics of Generics and various Generics collection types available in C#

Thanks!

Generic Class:à

What Are Generics?

http://mjxads.internet.com/RealMedia/ads/adstream_lx.ads/intm/webdev/www.15seconds.com/focus/netfeatures/L47/878413958/flex/WMBrands/Google_CP_31zzza/googlecpdevrocbobfeb10.html/646367374f6b756d494a304142624171?_RM_EMPTY_

http://mjxads.internet.com/RealMedia/ads/adstream_lx.ads/intm/webdev/www.15seconds.com/focus/netfeatures/L47/668235206/accessunit/WMBrands/MSFT_Azure_Showcase_GEMS_2f/au-Azure_Services_Platform_Center2.html/646367374f6b756d494a304142624171?_RM_EMPTY_

When we look at the term "generic", unrelated to the programming world, it simply means something that is not tied to any sort of brand name. For example, if we purchase some generic dish soap, soap that has no brand name on it, we know that we are buying dish soap and expect it to help us clean our dishes, but we really don't know what exact brand (if any) will be inside the bottle itself. We can treat it as dish soap even though we don't really have any idea of its exact contents.

Think of Generics in this manner. We can refer to a class, where we don't force it to be related to any specific Type, but we can still perform work with it in a Type-Safe manner. A perfect example of where we would need Generics is in dealing with collections of items (integers, strings, Orders etc.). We can create a generic collection than can handle any Type in a generic and Type-Safe manner. For example, we can have a single array class that we can use to store a list of Users or even a list of Products, and when we actually use it, we will be able to access the items in the collection directly as a list of Users or Products, and not as objects (with boxing/unboxing, casting).

"Generic" Collections as we see them today

Currently, if we want to handle our Types in a generic manner, we always need to cast them to a System.Object, and we lose any benefit of a rich-typed development experience. For example, I'm sure most of us are familiar with the System.Collection.ArrayList class in Framework v1 and v1.1. If you have used it at all, you will notice a few things about it:

1. It requires that you store everything in it as an object

public virtual int Add(object value);

public virtual object this[int index] {get; set;}

2. You need to cast up in order to get your object back to its actual Type

3. Performance is really lacking, especially when iterating with foreach()

4. It performs no type safety for you (no exceptions are thrown even if you add objects of different types to a single list)

System.Collections.ArrayList list = new System.Collections.ArrayList();

list.Add("a string");

list.Add(45); //no exception thrown

list.Add(new System.Collections.ArrayList()); //no exception

foreach(string s in list) { //exception will be thrown!

System.Console.WriteLine(s);

}

For some situations we may feel the need to implement IEnumerable and IEnumerator in order to create a custom collection of our given Type, that is, a Type-safe collection for our needs. If you had a User object, you could create another class (which implements IEnumerable and IEnumerator, or just IList) that allows you to only add and access User objects, even though most implementations will still store them as objects. It is a lot of work implementing these two interfaces, and you can imagine the work needed to create this additional collection class every time you wanted a Type-safe collection.

The third and final way of creating a collection of items is by simply creating an array of that type, for example:

string[] mystrings = new string[]{"a", "b", "c"};

This will guarantee Type safety, but is not very reusable nor very friendly to work with. Adding a new item to this collection would mean needing to create a temporary array and copy the elements into this new temporary array, resizing the old array, copying the data back into it, and then adding the new item to the end of that collection. In my humble opinion, this is too much work that tends to be very error prone.

What we need is a way to create a Type-safe collection of items that we can use for any type imaginable. This template, or generic class, should be able to perform all of the existing duties that we need for our collections: adding, removing, inserting, etc. The ideal situation is for us to be able to create this generic collection functionality once and never have to do it again. You must also consider other types of collections that we commonly work with and their functionality, such as a Stack (First in, Last out) or a Queue (First In, First out), etc. It would be nice to be able to create different types of generic collections that behave in standard ways.

In the next I will show you how to create your first Generic Type.

Creating Our First Generic Type

In this section we will create a very simple generic class and demonstrate how it can be used as a container for a variety of other Types. Below is a simple example of what a generic class could look like:

public class Col {

T t;

public T Val{get{return t;}set{t=value;}}

}

There are a few things to notice. The class name "Col" is our first indication that this Type is generic, specifically the brackets containing the Type placeholder. This Type placeholder "T" is used to show that if we need to refer to the actual Type that is going to be used when we write this class, we will represent it as "T". Notice on the next line the variable declaration "T t;" creates a member variable with the type of T, or the generic Type which we will specify later during construction of the class (it will actually get inserted by the Common Language Runtime (CLR) automatically for us). The final item in the class is the public property. Again, notice that we are using the Type placeholder "T" to represent that generic type for the type of that property. Also notice that we can freely use the private variable "t" within the class.

In order to use this class to hold any Type, we simply need to create a new instance of our new Type, providing the name of the Type within the "<>" brackets and then use that class in a Type-safe manner. For example:

public class ColMain {

public static void Main() {

//create a string version of our generic class

Col mystring = new Col();

//set the value

mystring.Val = "hello";

//output that value

System.Console.WriteLine(mystring.Val);

//output the value's type

System.Console.WriteLine(mystring.Val.GetType());

//create another instance of our generic class, using a different type

Col myint = new Col();

//load the value

myint.Val = 5;

//output the value

System.Console.WriteLine(myint.Val);

//output the value's type

System.Console.WriteLine(myint.Val.GetType());

}

}

When we compile the two classes above and then run them, we will see the following output:

hello

System.String

5

System.Int32

Even though we used the same class to actually hold our string and int, it keeps their original type intact. That is, we are not going to and from a System.Object type just to hold them.

Generic Collections

The .NET team has provided us with a number of generic collections to work with in the the latest version of the .NET Framework. List, Stack, and Queue are all going to be implemented for us. Let's see an example on how to use the provided Generic List class.

For this example we want to be able to hold a collection of a Type that we create, which we used to represent a User in our system. Here is the definition for that class:

namespace Rob {

public class User {

protected string name;

protected int age;

public string Name{get{return name;}set{name=value;}}

public int Age{get{return age;}set{age=value;}}

}

}

Now that we have our User defined, let's create an instance of the .NET Framework Generic version of a simple List:

System.Collections.Generic.List users

= new System.Collections.Generic.List();

Notice the new "Generic" namespace within the System.Collections namespace. This is where we will find all the new classes for our use. The "List" class within that namespace is synonymous with the typical System.Collections.ArrayList class, which I'm sure most of us are very familiar with by now. Please note that although they are similar there are several important differences.

So now that we have a Type-safe list of our User class, let's see how we can use this class. What we will do is simply loop 5 times and create a new User and add that User to our users collection above:

for(int x=0;x<5;x++)>

Rob.User user = new Rob.User();

user.Name="Rob" + x;

user.Age=x;

users.Add(user);

}

This should seem straight forward to you by now. In the next step we will iterate over that same collection and output each item to the console:

foreach(Rob.User user in users) {

System.Console.WriteLine(

System.String.Format("{0}:{1}", user.Name, user.Age)

);

}

This is slightly different that what we are used to. What you should notice right off the bat is that we do not have to worry about the Type being "Rob.User". This is because our generic collection is working in a Type-safe manner; it will always be what we expect.

Another way to output the same list would be to use a simple for() loop instead, and in this case we do not have to cast the object out of the collection in order to use it properly:

for(int x=0;x

System.Console.WriteLine(

System.String.Format("{0}:{1}", users[x].Name, users[x].Age)

);

}

No more silly casting or boxing involved. Here is the complete listing of the source plus the output of the result of executing the console application:

User.cs

namespace Rob {

public class User {

protected string name;

protected int age;

public string Name{get{return name;}set{name=value;}}

public int Age{get{return age;}set{age=value;}}

}

}

Main.cs

public class M {

public static void Main(string[] args) {

System.Collections.Generic.List users = new System.Collections.Generic.List();

for(int x=0;x<5;x++)>

Rob.User user = new Rob.User();

user.Name="Rob" + x;

user.Age=x;

users.Add(user);

}

foreach(Rob.User user in users) {

System.Console.WriteLine(System.String.Format("{0}:{1}", user.Name, user.Age));

}

System.Console.WriteLine("press enter");

System.Console.ReadLine();

for(int x=0;x

System.Console.WriteLine(System.String.Format("{0}:{1}", users[x].Name, users[x].Age));

}

}

}

Output

Rob0:0

Rob1:1

Rob2:2

Rob3:3

Rob4:4

press enter

Rob0:0

Rob1:1

Rob2:2

Rob3:3

Rob4:4

More on Generics

More Generics features in the latest release of the .NET Framework include Generic Methods and Constraints. A generic method is very straight forward. Consider this example:

public static T[] CreateArray(int size) {

return new T[size];

}

This static method simply creates a method of the given Type "T" and of the given "size" and returns it to the caller. An example of calling this method would be:

string[] myString = CreateArray(5);

This will new up an instance of our string array, with an initial size of 5. You should take time to investigate the new version of the framework. You will be surprised at all the little helpful features like this.

Lastly, we should take a quick look at constraints. A constraint is setup to limit the Types which the Generic can accept. Let's say for example we had a generic type:

public class Dictionary where K : IComparable {}

Notice the "where" clause on this class definition. It is forcing the K Type to be of Type IComparable. If K does NOT implement IComparable, you will get a Compiler error. Another type of constraint is a constructor constraint:

public class Something where V: new() {}

In this example V must have at least the default constructor available, if not the Compiler will throw an error.

Conclusion

No comments:

Post a Comment