views:

69

answers:

3

I'm quite new to C#, and have two questions regarding generic lists and extension methods. Sorry if the questions are a bit stupid..

What is the difference between:

public static IObjectWithTempID FindByTempID
    (this ObservableCollection<IObjectWithTempID > list, long tempID) 

and

public static IObjectWithTempID FindByTempID< E >
   (this ObservableCollection< IObjectWithTempID > list, long tempID)

I have tried to read up on the subject, but still don't understand :$

I have run into a strange issue. When I declare an ObservableCollection, such as this

ObservableCollection<TestObjectWithTempID> a =
    new ObservableCollection<TestObjectWithTempID>();

it is possible to call extension method

public static long FindByTempID
    (this IEnumerable< IObjectWithTempID > list, long tempID){}

on the list. It is surprisingly not possible to call extension method

public static long FindByTempID
    (this ObservableCollection< IObjectWithTempI D> list, long tempID){} 

though. What have I missed here?

+1  A: 

For your first question:

In the second method declaration the E in FindByTempID<E> is a type parameter. In other words it is a placeholder for a type, not an actual type. E can be used in the method body as if it were a real type. The general term for this type of programming is generics.

Mark Byers
+1  A: 

For 2, it needs to be:

TheMethod<T>(ObservableCollection<T> list)
    where T : ISomeInterface

Otherwise you could attempt to add any ISomeInterface instance to a more-specific list.

Marc Gravell
A: 

Having these extension methods

public static class Extenders
{
    public static void FindByTempID(this ObservableCollection<IObjectWithTempID> e, long tempID)
    {
    }
    public static void FindByTempID2(this IEnumerable<IObjectWithTempID> e, long tempID)
    {
    }
    public static void FindByTempID3(this ObservableCollection<TestObjectWithTempID> e, long tempID)
    {
    }
    public static void FindByTempID4<T>(this ObservableCollection<T> e, long tempID)
    {
    }
}

Then

var a1 = new ObservableCollection<TestObjectWithTempID>();
var a2 = new ObservableCollection<IObjectWithTempID>();

//a1.FindByTempID(1); /* Is not a collection of interface */
a1.FindByTempID2(1); // IEnumerable<T> is a generic list
a1.FindByTempID3(1); // It is a collection of TestObjectWithTempID
a1.FindByTempID4(1); // Identify the collection as ObservableCollection<TestObjectWithTempID>

a2.FindByTempID(1); // Is a collection of interface
a2.FindByTempID2(1); // IEnumerable<T> is a generic list
//a2.FindByTempID3(1); /* Is not a collection of TestObjectWithTempID */
a2.FindByTempID4(1); // Identify the collection as ObservableCollection<IObjectWithTempID>

IEnumerable<T>

BrunoLM