This workshop will be retired on May 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed C# Extension Methods!
You have completed C# Extension Methods!
Preview
Here are some tips on writing extension methods.
This video doesn't have any notes.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
As you can imagine extension methods could
be misused to cause a lot of confusion.
0:00
Notice how they appear to be part of the
original class, but in fact they aren't.
0:05
When writing extension methods,
I stick to a set of guidelines.
0:11
We'll go through these at
the end of the workshop.
0:15
A good guideline is to only create
extension methods that you could
0:17
realistically see as being part of
the original class that you're extending.
0:21
A great example of an extension method is
the IsEven method called on an integer.
0:25
So let's create a new class.
0:31
We'll call it, IntExtensions.
0:34
Again, we'll make it
a public static class.
0:43
And in here, we'll have a public
static method that returns a bool.
0:49
And it's called IsEven.
0:56
It's an extension method,
so I've to say this and
0:59
the type that it's going
to extend is integer.
1:03
I'll just call the parameter, value, here.
1:07
So in our method, we wanna check to
see if this value is an even value.
1:12
So we'll return.
1:18
To see if the value is even,
we can just divide the value by 2 and
1:20
to see if there's any remainder.
1:24
There's actually a special operator for
that in C#, it's called modulus.
1:27
So we can return the value %2.
1:33
And if that is equal to zero
then we know that value is even.
1:38
Otherwise it's false.
1:44
Another way to do this is
to use a bitwise operator.
1:47
What we can do is we can
take the integer value and
1:50
bitwise & it with the value 1,
1:53
because all odd integers
have their lowest bit as 1.
1:58
Now don't worry if you're not
familiar with bitwise operations.
2:04
This is just a very fast way to determine
if the last bit of a integer is 1.
2:08
So now we can call the IsEven
method on any integer
2:15
just like it was part
of the original class.
2:20
In order to call it though,
we need to make sure that we're
2:22
using the Treehouse.Common
namespace where we want to use it.
2:25
So up here, we need to add,
using Treehouse.Common.
2:29
Now down here, we can say 5.IsEven() and
this should return false.
2:37
Now it's conceivable that
the Treehouse.common namespace
2:45
has a lot of other classes in it.
2:49
We can reduce the scope even more
by using a static using directive.
2:51
So we can actually say using static
Treehouse.Common.IntExtensions.
2:56
This works with any static class.
3:04
And this makes it even more obvious that
3:07
we want to use the extension methods
in this IntExtensions class.
3:10
Now, instead of using the entire
Treehouse.Common namespace and
3:15
pulling in all of the other classes
that might be in that namespace,
3:19
we're just pulling in
the IntExtensions class.
3:23
And thereby, only pulling in
this IsEven extension method.
3:26
Remember that just because there's
an extension method that extends a type,
3:30
doesn't mean that it can be used
from anywhere the type is used.
3:35
Extension methods are scoped to
the namespace that they're declared in.
3:38
And we can further reduce that scope with
the using static directive just like this.
3:42
It's a good practice to declare extension
methods in a limited namespace.
3:48
For example,
3:53
we could have put the IntExtension
class in the system namespace.
3:54
But then this extension method
would be available everywhere.
3:58
And it wouldn't be very obvious that
this method isn't part of the original
4:02
integer type.
4:05
There are a number of classes and
4:07
interfaces that I find myself
writing extension methods for a lot.
4:08
One of those is the string class.
4:13
Let's take a look at the documentation for
the string class.
4:15
Here's the documentation for
the string class.
4:20
If we find the methods
that start with split.
4:22
Here we see the all of the methods that
start with split take a character array.
4:26
Now this first one,
4:32
actually takes a character array
that's actually a params argument.
4:34
And a params argument allows
us to pass in zero, one or
4:38
as many characters as we want and
what it does is it just
4:43
combines all those into a single
argument of type character array.
4:47
But the thing is, with params arguments,
4:52
is they have to be the last
argument in the method.
4:54
So, like this one right here,
takes a character array and the second
4:59
argument is the count which is the maximum
number of substrings it should return.
5:05
So the first argument here, actually, it's
just this regular old character array.
5:11
It's not a params,
5:17
which means we have to instantiate
a character array and pass that in.
5:18
So this makes it kind of
cumbersome when calling split,
5:24
if we only wanna pass in a single
character as the separator.
5:29
We don't wanna have to create a character
array every time we call the split method.
5:33
So we can leave this pain a little
bit by creating an extension method
5:38
that does this for us.
5:42
So let's go back to our code here and
I'll create a new file.
5:44
And it's a string extension, so
5:57
we'll put it in
the StringExtensions class.
6:00
So it'll have to be a public static class.
6:08
And we'll make a public static method
that returns a string array and
6:15
we'll call it split to match the other
ones and it will extend a string.
6:20
So, we'll say this string.
6:26
And here we have to decide what we
want to name the this parameter.
6:33
Now there's some debate about
what you should name this.
6:36
Personally, I like to call it this.
6:40
But the problem is,
is this is a keyword which,
6:43
we can't put it here because
it's a keyword in C#.
6:47
It causes the C# compiler
to kind of go into a fit.
6:50
So, [LAUGH] well,
it just causes a compiler error.
6:56
So what we can do if we want to
use a C# keyword as a variable
7:00
is we just prefix it with the @ symbol and
this makes a lot of sense because
7:05
this parameter is actually
called this parameter.
7:10
[LAUGH] So
calling it @this makes a lot of sense.
7:14
Some people don't like that convention and
7:18
it's fine if you don't
wanna do it this way.
7:20
Other people like to call
the this parameter target or
7:22
source or value or extended or
7:26
something that just makes sense for
the method that you code in, at that time.
7:30
I like to call it @this because I don't
have to think about what to name the this
7:34
parameter every time I
write an extension method.
7:38
It also makes argument null
exceptions really obvious and
7:41
I'll show you what I mean
in just a little bit.
7:45
Let's continue to write this method.
7:48
So we have to say which character we
want to separate the string on, so
7:51
pass in the separator.
7:56
And we also wanna say the maximum number
of times we want the string to split,
8:00
so we'll say int count.
8:04
The thing with extension methods is that
8:06
they can actually be called on
an object whose value is null.
8:09
Now, if we were to call
an instance method.
8:14
A method that's inside of
a regular class on null,
8:17
we'd get a NullReferenceException thrown.
8:21
But because split is actually just
a regular static method inside of a static
8:24
class and the object that is being
called on is just another argument or
8:31
parameter being passed into the method,
that means this can actually be null.
8:37
So we have to check for that, and
throw an exception if that's the case.
8:42
Just to demonstrate that these extension
methods are just really static
8:47
methods inside of a static class,
we can go back to the program class and
8:52
change where we're calling random item,
8:57
to actually be look like
a normal static method.
9:00
So we can say
IListExtensions.RandomItem() and
9:05
we can pass in our list here.
9:11
So now this looks a lot more like
the utility function that we had before.
9:15
So back in our split method,
we need to check for null.
9:24
So I'll say, if(@this == null),
9:28
Now I've said normally, if a method is
called on an object whose value is null
9:35
then we'll get a NullReferenceException.
9:39
But sometimes people actually
call extension methods
9:43
like a regular static method.
9:46
So instead of throwing
a NullReferenceException which really
9:48
wouldn't make sense if you're calling it
as a utility method or as a static method.
9:52
What we'll throw is
a ArgumentNullException.
9:56
So I'll say,
throw new ArgumentNullException.
10:00
And here, we pass in the name
of the argument that is null,
10:06
so in this case it's @this.
10:11
There we go.
10:15
Now there's a cool trick in C#.
10:16
There's an operator called
nameof that we can use.
10:18
That can make it so
that instead of passing in a string here,
10:24
we can actually just pass in the variable
itself and nameof will return
10:29
the actual name, the string,
that is the name of the variable.
10:34
This is handy because we may
wanna refactor in the future and
10:39
change the name of the variable here.
10:43
And as part of that refactoring,
the compiler will catch
10:46
that we've changed the variable and will
tell us we also need to change it here.
10:50
Strings can actually be quite dangerous
when we're using them to refer to code.
10:54
So it's always best to always
just stick in the code.
10:59
Now down here,
we can finish implementing our method.
11:03
So, we want to return.
11:05
And we'll just call the regular
split method from the string class.
11:08
So we'll say @this.Split().
11:12
Now, this is how we would
normally call this method.
11:16
We would create a new array.
11:20
And in the array, we would specify
the separator that we want to split on.
11:25
And then pass in count.
11:35
So there you go.
11:37
So now when we're using this method,
instead of calling string.Split,
11:38
creating a new array with
the separator we wanna split on,
11:44
we can just call this method like so.
11:48
We'll just say "mySTring".Split('S',
11:51
3) like that.
11:59
Pretty nifty.
12:02
So I mentioned before that
calling this parameter @this can
12:09
actually help a little bit when
we have argument null exceptions.
12:13
So let's go to program and
let's cause one of these exceptions.
12:19
So let's create a string.
12:27
And we'll just call it myString,
and set it equal to null.
12:29
And we'll call myString.Split.
12:37
And notice now that there are a lot
of different split methods in this
12:45
string class.
12:49
We can go down here, these ones
are all part of the regular class.
12:50
And we'll just pass in you can
split on a comma, three times.
12:58
And it's not seeing our new extension
method because we don't have
13:04
the namespace up here.
13:09
So let's bring this back to
using static Treehouse.Common.
13:10
There we go.
13:21
So let's run this and
let's see what kind of exception we get.
13:22
All right, so
because we're in the debugger,
13:26
it breaks right here where
the ArgumentNullException is being thrown.
13:28
And here we see ArgumentNullException
was unhandled and
13:33
we go down here,
we can click on this view detail.
13:37
And here we see value cannot be
null parameter name is this.
13:40
Now my logic for
calling the parameter this is because if
13:46
an ArgumentNullException is thrown and the
parameter name is this, then I know right
13:51
away that the method that threw this
exception is a extension method.
13:55
So that gives me a lot better
idea of where to look.
14:01
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up