Method Precedence9:04 with Jeremy McLain
With extension methods, it's possible to have multiple methods with the same name and take the same parameters. But which one will be called?
In the split method we just coded, 0:00 we checked to make sure that this parameter isn't null. 0:02 Sometimes we want the parameter to be able to be null. 0:06 For example there's a method called is null or empty in the string class. 0:09 Let's go take a look at that. 0:15 Here's the is null or empty method in the string class and notice that it's static. 0:16 The reason it's static is because if the string is null, 0:22 you can't call a method on it, otherwise you'll get a null reference exception, 0:28 but with extension methods you can call a method on something that is null. 0:33 So let's write our own version of the is null or empty method for string. 0:38 So say public static and 0:43 notice that I'm doing this in the string extension static class again. 0:46 In return bool and the name is null or empty. 0:51 It takes, this extend string. 0:59 We'll just call it this, and inside here 1:03 we'll just call string.is null or empty and 1:07 pass in this and we'll want to return that. 1:12 Now let's go over to program.cs and try it out. 1:19 So here we have our null myString. 1:23 So I can just call myString.IsNullOrEmpty like so. 1:26 Now, one thing you may not know about the string class is that 1:33 the string class actually implements the IEnumerable interface. 1:37 Let's take a look. 1:43 As you can see, a string is an I numerable of char. 1:48 So it could actually move our is null or empty extension method into 1:53 the I Enumerable extensions class and extend all I Enumerables. 1:58 Let's see how that would look. 2:03 First I'll create a new class to contain this extension method. 2:05 I'll call it IEnumerable extensions. 2:13 Make it public. 2:22 Make it static. 2:24 And we'll copy. 2:29 And I'm not gonna delete it from here. 2:33 I'm actually just gonna copy it from here. 2:35 We'll copy that over here. 2:43 We will change this so that is null or 2:50 empty can be called on any I numerable of T. 2:52 So say this I 2:57 numerable of T. 3:01 And instead of calling string. 3:06 isnullorempty we'll 3:08 return @this = null or 3:13 !@this.Any(). 3:18 The Any method is actually a extension method provided by system.link. 3:23 If you're familiar with the link you may know that link 3:30 relies heavily on extension methods and any is one of those extension methods. 3:33 There is something else subtle happening here, this or 3:39 condition is actually taking advantage of a feature called short circuiting. 3:42 Remember calling Any on this variable 3:48 will throw a null reference exception if this is null, but 3:52 if this is null then the first part of this condition will be true. 3:56 Short circuiting means that the first condition of an or 4:02 that evaluates to true will cause the entire expression to be true. 4:06 If that happens, any of the later conditions or 4:12 expressions in the condition, are no longer evaluated, 4:15 because C Sharp already knows that the expression should be true. 4:19 So if this is null, then this code right here will never be called. 4:24 We're now in a very interesting situation now. 4:29 We now have two methods that are named the same that can be called on the same type. 4:32 Here I'll demonstrate to you. 4:39 Here we have myString.IsNullOrEmpty. 4:43 Let's see what happens if we comment out 4:47 the isNullorempty method in the string extensions class. 4:50 If we go back to Programm.cs we don't see any red squiggly lines. 4:57 And this will compile just fine. 5:02 See the build succeeded. 5:07 So I wonder which is null or empty method will be called. 5:09 To test this out, let's go back here and uncomment this method. 5:14 And then let's put a break point inside of it. 5:18 Let's also put a break point inside the IEnumerable extensions version. 5:22 Let's go ahead and run this. 5:28 Notice that the is null or 5:32 empty method inside of the string extensions class was called. 5:34 Instead, of the is null or 5:39 the empty method inside of the IEnumerable extensions class. 5:41 So how did C Sharp know which method should be called? 5:45 Well, C Sharp knows that my string is of type stream. 5:49 It's also of type IEnumerable of char. 5:54 But string is a more specific type. 5:59 So when C Sharp determines which extension method should be called, 6:02 it always calls the one that deals with the more specific type. 6:08 Meaning it's the farthest down in the inheritance chain. 6:13 We can see another example of this in link. 6:17 Let's go back to the browser, And search for 6:22 the system.collections.generic. 6:27 .list documentation. 6:33 List contains a method called contains, 6:42 which takes a parameter of type T. 6:47 But link also provides a method called contains. 6:50 Here these are all of the methods provided by 6:56 link that can be used on the list class. 6:59 These are all extension methods, the contains method provided by link and 7:02 the contains method provided by the list class have identical signatures. 7:06 The C-sharp knows that it should call contains on a list when list is passed in 7:11 and it should call links contains when anything else is passed in. 7:16 Let's create another extension method for IEnumerable. 7:21 A very common extension method that many people use on IEnumerable 7:24 that isn't provided by link is the is empty method. 7:28 So say public static bool is empty. 7:33 This IEnumerable of type 7:39 T You need to provide the type parameter here. 7:43 And all this will do is return if there are not any 7:54 items in the IEnumerable. 8:00 Now it isn't unimaginable that Microsoft could in the future 8:05 add this identical method to .net. 8:10 After all it is a pretty obvious method to have. 8:12 If Microsoft added this method and we upgraded to that new version of .net, 8:15 and we were using our own extension method called is empty. 8:21 We get a compiler error telling us that there are ambiguous methods and 8:25 the compiler doesn't know which one to use. 8:29 In that case, all we need to do is go back and remove our is empty method. 8:33 Extension methods should have a very straightforward and 8:39 obvious implementation. 8:43 This makes them more reusable. 8:44 But it also helps protect against the situation 8:47 where a method with the same name is added to the class in the future. 8:49 If you implement them the way you would expect them to be implemented 8:54 it's more likely that they will have the same behavior and 8:57 you can just remove your implementation of the extension method. 9:00
You need to sign up for Treehouse in order to download course files.Sign up