I have the following code:

static void foo<T>(this List<T> list, T t)
        {
            ...
        }

So in order to call the extension method I'll have to do this:

myList.foo<myType>(myVar);

Is it possible to change my code so that I can call my method like this:

myList.foo(myVar);

For, example the Remove function in List is called without specifying the type (myList.Remove(myVar) and not myList.Remove<myType>(myVar)).

Recommended Answers

All 9 Replies

Yes you can remove the <T> from the name of the function, like so:

static void foo(this List<T> list, T t)
      {
      ...
      }

Yes you can remove the <T> from the name of the function, like so:

static void foo(this List<T> list, T t)
      {
      ...
      }

Well, yes that's the first thing I tried doing, but:
The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?)

No, since List<T> is technically not a type until you've given it one. So an extension method for a generic has to have a type so it 'knows' which type it is extending.

No, since List<T> is technically not a type until you've given it one. So an extension method for a generic has to have a type so it 'knows' which type it is extending.

Well isn't the type of List<T> determined during its initialization and not when one of its generic methods is called? If so, can't the method evaluate the list's type at runtime? I mean that's the whole point of generics, isn't it?

No, it's determined at compile time. The compiler generates a new type based on the generic version of List<T> given the type specified.

It's possible to do this at runtime (reflection), but still the extension method would need to know what type it is extending, thus you need to give it the T parameter.

Well, what do you mean the extension method doesn't know what type it's extending? Can't the compiler generate the new type based on the list it's extending and whose type it knows?

List<string> myList = new List<string>();

static void foo(this List<T> list, T t)
{
    ...
}

static void main()
{
    myList.foo();
}

Can't the compiler simply determine that myList contains elements of type string and therefore evaluate T as a string?

What about the Remove() method. How come it doesn't ask for a type?

You need to remember that at its heart, C# is a statically typed language. Generics came about in 2.0, and extension methods in 3.0. It isn't until 4.0 that we get the dynamic keyword.

While it would be possible for them to reflect over the class at runtime, you'd lose a lot of the static typing done. Also you'd lose the ability of the compiler to determine if a method is valid for a specific type. Method calls would have to reflect over the extension code each time to determine if there is an extension method to use, or if it should use the normal method based on parameters to the method call.

This would slow everything down, and no one wants slow.

I didn't manage to understand much, but it turns out that the following code is valid for some reason:

List<string> myList = new List<string>();
     
    static void foo<T>(this List<T> list)
    {
        ...
    }
     
    static void main()
    {
        myList.foo();
    }

I don't know why that's so, but it solves my problem.

Odd. The compiler must be doing more work than I thought it was :) Now I have to wonder what the point of method<T>(this T ...) is for. Time to start reading, I guess :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.