In the lesson about extension methods, we learned that they are a nice way of adding extra functionality to existing types, and we did that by adding a static method inside a static class, that took a type parameter prefixed with the this keyword, like this:
So, although my original Book class does not contain a method called SellBook(), I am able to call it inside the Main() method because I declared an extension method for the Book class, and this static SellBook() method took a Book type parameter prefixed with the this keyword, that signals the compiler that the method is intended as an extension method for the Book type.
But why the this keyword? What does it mean, what does it represent?
Let’s recreate the above example without using an extension method:
See code changes Now, when I’m instantiating a new
Book in my
Main() method, think about what the
new operator has to do: it has to go on the Heap memory and allocate enough RAM memory for a
Book. Well… how big is a
Book? If we look inside it, we can see that each
Book has its own copy of the
copiesSold int and the
bookName string fields. If we declared them as static, they would be shared amongst all instances of
Book, but we didn’t. So, in reality, a
Book is the size of an
int plus the size of a
string. You might be wondering about the extra size that needs to be allocated for the
SellBook() method of each of the
Book instances, but here is the tip of the day: ALL METHODS IN C# ARE STATIC. Even the instance ones, where we don’t place the
static keyword on them, they just look like instance methods! This is because it makes no sense for the compiler when I say
new Book() to actually make a copy of the
SellBook() method, because the code inside it is identical for any
Book instance. It doesn’t change from instance to instance. I will prove this to you, but before that, you should know that on instance methods, the compiler implicitly gives you the
this keyword on each non static member you use. So, yes, we can write the
SellBook() method like this: but the compiler will implicitly add the this keyword on all non static members used inside it: But now, we will take the control away from the compiler and we will turn our
SellBook() from an instance method to a static method. Of course, from the lesson static members we already know that we cannot access instance members inside static methods, so we also need to pass a
Book parameter to the
SellBook() method, in order for it to know to which
Book we are referring to: See code changes Obviously, inside the
Main() method I can no longer syntactically call the
SellBook() method like that, I have to call it through the class itself, because it belongs to the class blueprint, not its copies. The result is the same: So, I am just being more explicit, instead of relying on the compiler to pass the this instance, I am passing the instance myself. And since each instance of
Book has its own copy of the non static members
copiesSold and
bookName, if I pass different instances of
Book as parameters to the static
SellBook() method, each of these instances will have their copy of
copiesSold variable incremented, independently one from another. I can create another Book instance and sell it through the same static method, and still have individual results: See code changes notice that the “The three Musketeers” book has its own copy of
copiesSold, which is incremented separately. So, hopefully, that’s making sense: all methods are really static, the compiler just adds the
this keyword for us. However, you have to admit, the syntax for selling a book in this case is not really nice, because we have to say
Book.SellBook(firstBook), instead of just saying
firstBook.SellBook(). And this is the beauty of extension methods, in fact, this is the reason why we say
this Book in extension methods parameters, this is the reason why the designers of the C# language decided to use
this, because, really, it is the
this argument that you are giving it on. If I modify my code to convert the
SellBook() method into an extension method, I can still call
SellBook() as if it was an instance method: See code changes It looks like an instance method, it feels like an instance method, but it’s really just a static method. And instance methods do the same, behind the curtains. Tags: extension methods, linq, methods, static members, this
Legend:
Legend:
Legend:
Legend: