Duplicate of http://stackoverflow.com/questions/155260/what-is-the-functionality-within-c
Actually i want to know 'why and when should i use generics?'.
What is the need for it?
Duplicate of http://stackoverflow.com/questions/155260/what-is-the-functionality-within-c
Actually i want to know 'why and when should i use generics?'.
What is the need for it?
Generics basically remove the need to cast and objects into their base type.
e.g. if you want to store a group of Foos in a List.
You used to have to either create your owen FooList or cast the item as objects.
All this takes you time and the complier.
With Generics all you have to do is sat List it checks you types and speeds up you programs. (no boxing and unboxing)
Suppose you yourself is an algorithm which can sort whatever objects that can be compared pair-wise (playing-cards, CDs, business cards, whatever). You're not actually interested in what these concrete objects are provided you can compare them. Thus you become a generic (here "generic" is used in a broad term, not in C# sense) algorithm.
Generics in .NET help facilitate this particular kind of behavior not only in terms of algorithms (generic functions), but also in terms of generic types (classes, structs, delegates, interfaces).
Just to add to what everyone else will tell you, more practically, try doing something with an ArrayList
or System.Array
object and then try doing it with a List<T>
and you can immediately see the how generics allows you to write more readable code and write it quicker too.
Generics are a way of ensuring Type Safety at Compile time in C#.
Example- Pre-Generics:
class Person
{
string name;
string lastname;
public Person(string _name ) { this.name = _name; }
}
class ClientCode
{
public static void Main()
{
//create a list of person
ArrayList personList = new ArrayList();
Person p1 = new Person("John");
Person p2 = new Person("Ram");
personList.Add(p1);
personList.Add(p2);
// BUT, someone can do something like:
// ArrayList does not stop adding another type of object into it
object q = new object();
personList.Add(q);
// while accessing personlist
foreach(object obj in personlist)
{
Person p = obj as Person;
// do something, for person
// But it will fail for last item in list 'q' since its is not person.
}
}
}
Example- Post-Generics:
class ClientCode
{
public static void Main()
{
//create a list of person
List<Person> personList = new List<Person>();
Person p1 = new Person("John");
Person p2 = new Person("Ram");
personList.Add(p1);
personList.Add(p2);
// Someone can not add any other object then Person into personlist
object q = new object();
personList.Add(q); // Compile Error.
// while accessing personlist, No NEED for TYPE Casting
foreach(Person obj in personlist)
{
// do something, for person
}
}
}
I blogged about it a long time ago, here. I was working with XML, and I wanted a helper that would get an XmlElement or an XmlAttribute (based on an XPath) and let me work with it. It was a nice simple example I worked through in the real world when generics were fairly new to C#.
Generics let you parameterize code over types in the same way that arguments let you parameterize it over values. That probably doesn't explain a whole lot, so lets go through it a step at a time:
Imagine you want a program to print "I like bunnies". You write this:
static void Main()
{
ILikeBunnies();
}
void ILikeBunnies() { Console.WriteLine("I like bunnies"); }
All well and good. But you also like cheese, so now you have:
static void Main()
{
ILikeBunnies();
ILikeCheese();
}
void ILikeBunnies() { Console.WriteLine("I like bunnies"); }
void ILikeCheese() { Console.WriteLine("I like cheese"); }
You notice that your two functions are almost identical. You want to reuse the same function, but provide different values for what you like:
static void Main()
{
ILike("bunnies");
ILike("cheese");
}
void ILike(string what) { Console.WriteLine("I like " + what); }
This is what function arguments are for: they let you reuse the same code with different values.
Generics are like that, but instead of passing in different values, you pass in types. Lets say you've got code that needs to bundle two strings into an array:
static void Main()
{
string[] s = Pair("a", "b");
}
string[] Pair(string a, string b) { return new string[] { a, b }; }
Fine and dandy. Later you realize you also need to bundle ints into an array:
static void Main()
{
string[] s = Pair("a", "b");
int[] i = Pair(1, 2);
}
string[] Pair(string a, string b) { return new string[] { a, b }; }
int[] Pair(int a, int b) { return new int[] { a, b }; }
Just like before, we can see there's a bunch of redundancy there. What we need is a function that returns a pair of whatever and a way to pass in the type of what we want a pair of. This is what generics are for:
static void Main()
{
string[] s = Pair<string>("a", "b");
int[] i = Pair<int>(1, 2);
}
T[] Pair<T>(T a, T b) { return new T[] { a, b }; }
The angle brackets let you pass in a type to a function in the same way parentheses let you pass in values. "T" here is the name of a type argument just like "what" was the value argument above. Any place T appears in the function will be replaced with the actual type you pass in (string and int in the example).
There's a bunch of stuff you can do with generics beyond this, but that's the basic idea: generics let you pass types into functions (and classes) in the same way arguments let you pass in values.