An extension method, in brief, is the ability to "extend" a type
through some syntactical sugar. Now, I say “extend” in quotes because it really
does nothing to the other type at all, it simply defines a static method in a
static class and identifies the type you are "extending" as the first
parameter by preceding it with the this keyword in the
parameter list.
For example, you could say:
1: // class has to be static
2: public static class IntExtensions
3: {
4: // method has to be static, first parameter is tagged with the 'this'
5: // keyword, the type of the parameter is the type that is extended.
6: public static int Half(this int source)
7: {
8: return source / 2;
9: }
10: }
1: // Invoking as if it were an ordinary, static method
2: var two = IntExtensions.Half(4);
1: // Extension method behave as if they were really members of
2: // the type they extend, thus we can call Half() on any integer.
3: var two = 4.Half();
1: public static class IntExtensions
2: {
3: public static int Half(this int source)
4: {
5: return source / 2;
6: }
7:
8: public static int Cube(this int source)
9: {
10: return (int)Math.Pow(source, 3);
11: }
12:
13: public static int Square(this int source)
14: {
15: return (int)Math.Pow(source, 2);
16: }
17: }
1: // The repetition of the type name and nesting gets confusing...
2: var ans = IntExtensions.Square(IntExtensions.Half(IntExtensions.Cube(13)));
1: // Much better, says take 13, cube it, half it, square it.
2: var ans = 13.Cube().Half().Square();
Now, even with the this keyword, this is really just a static
method like any other and thus you could invoke it like:
But the magic of extension method's syntactical sugar is that you can invoke
them as if they were first-class methods of the type they "extend":
Once again, this is really just syntactic sugar. The instance of the
type being “extended” is passed as the first parameter into the static
method in the generated byte-code for you. Thus, the shorter, cleaner
syntax will in the end compile just like the more traditional syntax in the
previous example. But this syntactic sugar can not only shorten simple
calls like the above, but can allow for chaining of multiple methods (extension
and first-class both) in a very fluent way.
Let’s expand our integer extensions with a few more ideas:
Now, what if you had the above methods and wanted to take 13, Cube()
it, then take Half(), then Square() the
result using these methods? If you wanted to do this using traditional static
method syntax, you'd have to write:
Ugh, that's a mess! But with extension method syntactical sugar, you get a
much cleaner and easier to read result:
So, we see there is a lot of power here to extend types in a very fluent
way. But I've only hinted at one of the things that make extension
methods so very powerful. I said they could be used to "extend" any type.
I don’t mean just struct or class or
primitives, I mean interfaces as well.
(Practice Makes a Man Perfect)
(Practice Makes a Man Perfect)
No comments:
Post a Comment