views:

5602

answers:

8

What are some examples of you would use generics in C#/VB.Net and why would you want to use generics?

+1  A: 

See MSDN article.

Pawel Krakowiak
+4  A: 

Have a look at the MSDN introduction to C# generics.

Mark Cidade
+20  A: 

Simply, you declare a type or method with extra tags to indicate the generic bits:

class Foo<T> {
    public Foo(T value) {
        Value = value;
    }
    public T Value {get;private set;}
}

The above defines a generic type Foo "of T", where the T is provided by the caller. By convention, generic type arguments start with T. If there is only one, T is fine - otherwise name them all usefully: TSource, TValue, TListType etc

Unlike C++ templates, .NET generics are provided by the runtime (not compiler tricks). For example:

Foo<int> foo = new Foo<int>(27);

All Ts have been replaced with int in the above. If necessary, you can restrict generic arguments with constraints:

class Foo<T> where T : struct {}

Now Foo<string> will refuse to compile - as string is not a struct (value-type). Valid constraints are:

T : class // reference-type (class/interface/delegate)
T : struct // value-type except Nullable<T>
T : new() // has a public parameterless constructor
T : SomeClass // is SomeClass or inherited from SomeClass
T : ISomeInterface // implements ISomeInterface

Constraints can also involve other generic type arguments, for example:

T : IComparable<T> // or another type argument

You can have as many generic arguments as you need:

public struct KeyValuePair<TKey,TValue> {...}

Other things to note:

  • static members etc are defined per generic type combination - so a static field on Foo<int> is separate to that on Foo<float>.
  • methods can be generic too - try to avoid using the same names as the class uses, as you won't be able to disambiguate
  • nested types inherit the generic types from their parents

for example:

class Foo<T> {
    class Bar<TInner> {} // is effectively Bar<T,TInner>, for the outer T
}
Marc Gravell
+2  A: 

Example 1: You want to create triple class

Class Triple<T1, T2, T3>
{
   T1 _first;
   T2 _second;
   T3 _Third;
}

Example 2: A helper class that will parse any enum value for given data type

static public class EnumHelper<T>
{
   static public T Parse(string value)
   {
       return (T)Enum.Parse(typeof(T), value);
   }
}
Brijesh Mishra
+1  A: 

The most common reasons and use cases for generics are described in the MSDN documentation mentioned before. One benefit of generics I'd like to add is that they can enhance the tool support in the development process. Refactoring tools like those integrated in Visual Studio or ReSharper rely on static type analysis for providing assistance while coding. As generics usually add more type information to your object model, there is more information for such tools to analyse and to help you coding.

On a conceptual level, generics help you solving "cross-cutting" concerns independently from your application domain. Regardless whether you are developing a financial application or a book store, you will sooner or later need to maintain collections of things, be it accounts, books or whatever. The implementation of such collections usually needs to know little to nothing about the things to be maintained in those collections. Hence, the generic collections shipped with the .NET framework are a primary example for a generics use case.

Sven Künzler
+1  A: 

One common, and extremely helpful, use of generics is strongly-typed collection classes. Traditionally, all collection classes had to be passed objects, and return objects when queried. You had to handle all the type conversion yourself. With generics, you don't have to do that. You can have List(Of Integer), and when you request values from it, you'll get integers. You won't get objects that you then have to convert to integers.

Daniel Straight
+1  A: 
    private void button1_Click_1(object sender, RoutedEventArgs e)
    {
        TextValue<string, int> foo = new TextValue<string, int>("",0);
        foo.Text = "Hi there";
        foo.Value = 3995;
        MessageBox.Show(foo.Text);
    }

    class TextValue<TText, TValue>
    {
        public TextValue(TText text, TValue value)
        {
            Text = text;
            Value = value;
        }
        public TText Text { get; set; }
        public TValue Value { get; set; }
    }
dewelloper
A: 
    private void button1_Click_1(object sender, RoutedEventArgs e)
    {
        TextValue<string, int> foo;
        List<TextValue<string, int>> listTextValue = new List<TextValue<string, int>>();
        for (int k = 0; k < 5; ++k)
        {
            foo = new TextValue<string, int>("",0);
            foo.Text = k.ToString();
            foo.Value = k;
            listTextValue.Add(foo);
            otherList.
            MessageBox.Show(foo.Text);
        }

    }

    class TextValue<TText, TValue>
    {
        public TextValue(TText text, TValue value){Text = text; Value = value;}
        public TText Text { get; set; }
        public TValue Value { get; set; }
    }
dewelloper