Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are we extending when creating a generic extension method?

Tags:

c#

public static class MyClass
{
    public static void Print<T>(this T theObject)
    {
        Console.WriteLine("The print output is " + theObject.ToString());
    }
}

In the given class I've specified a generic as the type to extend via the this keyword. Being that I've delayed the definition of the type until compile time, how does intellisense (and anything else involved) know what type I am extending? Does C# simply default to the top level System.Object?

like image 739
P.Brian.Mackey Avatar asked Apr 04 '12 15:04

P.Brian.Mackey


2 Answers

Yes, it's System.Object unless you add a type constraint.

like image 155
Donut Avatar answered Oct 06 '22 01:10

Donut


Being that I've delayed the definition of the type until compile time, how does intellisense (and anything else involved) know what type I am extending? Does C# simply default to the top level System.Object?

Those that say that this is an extension on System.Object are wrong. For one, this method will not box value type inputs, but an extension method defined on System.Object will.

The extension method you've defined is an generically parameterized extension method. It can be applied to any type that is valid as generic type parameter.

If you're not already thinking about extension methods in the following way, this might help you understand them a little bit better. Extension methods are just a trick that the language specification lets us get away with. Extension methods are really just static methods in static classes that we can call as if they were instance methods. So

static class Foo {
    public static void M(this object obj) { }
}

is just a static method in a static class. You could call it like this:

Foo.M(obj);

but we can call it like it's an instance method:

obj.M();

Thus, when you have a generic extension method, stop for a minute and think about it as a static method in a static class

static class Foo {
    public static void M<T>(this T obj) { }
}

You could call it like this:

object obj;
Foo.M(obj);

or you can call it like this:

obj.M();

There's no difference to the compiler which you write.

So, now you're thinking of it as a regular generic method. But surely when you think about it from this perspective you understand that the compiler will let you invoke this method on any type that is valid as a generic type parameter. And thus, you now understand why it can be thought of as an extension method on any type that is valid as a generic type parameter.

like image 37
jason Avatar answered Oct 06 '22 00:10

jason