tags:

views:

620

answers:

7

I have been learning about the basics of C# but havent come across a good explenation of what this is.

var l = new List<string>();

I dont know what the < string > is doing or if its the List that is doing the magic. I have also seen objects been thrown within the < > tags.

Can someone explain this to me please with examples.

+1  A: 

This is .NET Generics. The type within the < > denotes the type of element contained in the list.

with ArrayList you'd have to cast the elements inside...

int x = (int)myArrayList[4];

with List you can avoid that step because the compiler already knows the type.

int x = myList[4];

Generics are available in .NET 2.0 and later.

Ben Scheirman
+1  A: 

Those are generics. You are making a List that only contains strings. You could also say

List<int>

and get a list that only contains ints.

Generics is a huge topic, too big for a single answer here.

Eric Z Beard
Thanks for that and i have edited the question
Ólafur Waage
NP. I deleted my suggestion as well. Into the memory hole they go.
Eric Z Beard
+1  A: 

Those are known as Generics (specifically List is a generic class).

Reading from MSDN

bdukes
+5  A: 

It's generics - it's a form of type parameterisation. In your example, it's making l refer to a list of strings - the list will only ever contain strings: the compiler treats it (pretty much) as if everywhere that the API docs mention "T" it actually says "string". So, you can only add strings to it, and if you use the indexer you don't need to cast to string, etc.

To be honest, giving generics detailed coverage on an online forum is pretty much impossible. (In C# in Depth, I take nearly 50 pages talking about generics.) However, armed with the name of the feature, you should be in a much better position to find out more. The MSDN "Introduction to C# Generics" is probably a good starting point.

Asking specific questions about generics on SO is likely to yield good results - I just don't think it can really be covered properly in one question/answer.

Jon Skeet
Thanks, a nice answer.
Ólafur Waage
+22  A: 

That is the generic syntax for C#.

The basic concept is that it allows you to use a Type placeholder and substitute the actual real type in at compile time.

For example, the old way:

ArrayList foos = new Arraylist();
foos.Add("Test");

worked by making ArrayList store a list of System.Objects (The base type for all things .NET).

So, when adding or retrieving an object from the list, The CLR would have to cast it to object, basically what really happens is this:

foos.Add("Test" as System.Object);
string s = foos[1] as String.

This causes a performance penalty from the casting, and its also unsafe because I can do this:

ArrayList listOfStrings = new ArrayList();
listOfStrings.Add(1);
listOfStrings.Add("Test");

This will compile just fine, even though I put an integer in listOfStrings.

Generics changed all of this, now using Generics I can declare what Type my collection expects:

List<int> listOfIntegers = new List<int>();
List<String> listOfStrings = new List<String>();

listOfIntegers.add(1);

// Compile time error.
listOfIntegers.add("test");

This provides compiletime type safety, as well as avoids expensive casting operations.

The way you leverage this is pretty simple, though there are some advanced edge cases. The basic concept is to make your class type agnostic by using a type placeholder, for example, if I wanted to create a generic "Add Two Things" class.

public class Adder<T>
{
   public T AddTwoThings(T t1, T t2)
   {
       return t1 + t2;
   }
}

Adder<String> stringAdder = new Adder<String>();
Console.Writeline(stringAdder.AddTwoThings("Test,"123"));

Adder<int> intAdder = new Adder<int>();
Console.Writeline(intAdder.AddTwoThings(2,2));

For a much more detailed explanation of generics, I can't recommend enough the book CLR via C#.

FlySwat
fyi the performance penalty when using ArrayLists is when boxing and unboxing value types occurs (structs, ints, floats, etc). There is no appreciable performance penalty for casting the object reference back to a string reference.
Robert Paulson
Additionally, it's a minor point, but Generics (or constructed types) in .net aren't realized (constructed) until runtime. The compiler only checks your code at compile-time and ensure that for IList<T>.Add(T) that the var in `Add(var)` is implicitly convertable to T.
Robert Paulson
The AddTwoThings example has been covered numerous times on SO, and is not valid.
erikkallen
+1  A: 

This is generics in action. A regular List stores items of type Object. This requires casting between types. This also will allow you to store any kind of item in one instance of a list. When you are iterating through items in that list you cannot be sure that they are all of a certain type (at least not without casting each item). For instance lets say you create a list like this:

List listOfStrings = new List();

Nothing prevents someone from doing something like this:

listOfStrings.add(6); //Not a string

A generic list would allow you to specify a strongly-typed list.

List<string> listOfStrings = new List<string>();
listOfStrings.add("my name"); //OK
listofStrings.add(6); //Throws a compiler error

There is a more thorough examples on here Generics

Micah
A: 

< > is for generics. In your specific example, it means that the List is a List of strings, not say a list of ints.

Generics are used to allow a type to be, well, generic. It's used ALOT in Collections to allow them to take different types so that they can function much like a normal array and still catch invalid types being assigned at compile time. Basically it allows a class to say "I need to be associated with some specific type T, but I don't want to hard code exactly what that type is, and let the user select it.". A simple array for instance might look something like:

public class MyArray<T> {
    private T[] _list;

    public MyArray() : this.MyArray(10);
    public MyArray(int capacity)
    { _list = new T[capacity]; }

    T this[int index] {
        get { return _list[index]; }
        set { _list[index] = value; }
    }
}

Here, we have a private list of type T that is accessed by using our class like a normal array. We don't care what type it is, it doesn't matter to our code. But anyone using the class could use it as, say MyArray<string> to create a list of strings, while someone else might use it as MyArray<bool> and create a list of flags.

Matthew Scharley