13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

258 CHAPTER 10 Extension methodsList<strong>in</strong>g 10.2WebRequest request = WebRequest.Create("http://mann<strong>in</strong>g.com");us<strong>in</strong>g (WebResponse response = request.GetResponse())us<strong>in</strong>g (Stream responseStream = response.GetResponseStream())us<strong>in</strong>g (FileStream output = File.Create("response.dat")){StreamUtil.Copy(responseStream, output);}List<strong>in</strong>g 10.2 is quite compact, and the StreamUtil class has taken care of loop<strong>in</strong>g andask<strong>in</strong>g the response stream for more data until it’s all been received. It’s done its jobas a utility class perfectly reasonably. Even so, it doesn’t feel very object-oriented. We’dreally like to ask the response stream to copy itself to the output stream, just like theMemoryStream class has a WriteTo method. It’s not a big problem, but it’s just a littleugly as it is.Inheritance wouldn’t help us <strong>in</strong> this situation (we want this behavior to be availablefor all streams, not just ones we’re responsible for) and we can’t go chang<strong>in</strong>g theStream class itself—so what can we do? With <strong>C#</strong> 2, we were out of options—we had tostick with the static methods and live with the clums<strong>in</strong>ess. <strong>C#</strong> 3 allows us to change ourstatic class to expose its members as extension methods, so we can pretend that themethods have been part of Stream all along. Let’s see what changes are required.10.2 Extension method syntaxUs<strong>in</strong>g StreamUtil to copy a web response stream to a fileExtension methods are almost embarrass<strong>in</strong>gly easy to create, and simple to use too.The considerations around when and how to use them are significantly deeper thanthe difficulties <strong>in</strong>volved <strong>in</strong> learn<strong>in</strong>g how to write them <strong>in</strong> the first place. Let’s start offby convert<strong>in</strong>g our StreamUtil class to have a couple of extension methods.10.2.1 Declar<strong>in</strong>g extension methodsYou can’t use just any method as an extension method—it has to have the follow<strong>in</strong>gcharacteristics:■ It has to be <strong>in</strong> a non-nested, nongeneric static class (and therefore has to be astatic method).■ It has to have at least one parameter.■ The first parameter has to be prefixed with the this keyword.■ The first parameter can’t have any other modifiers (such as out or ref).■ The type of the first parameter must not be a po<strong>in</strong>ter type.That’s it—the method can be generic, return a value, have ref/out parameters otherthan the first one, be implemented with an iterator block, be part of a partial class, usenullable types—anyth<strong>in</strong>g, as long as the above constra<strong>in</strong>ts are met.We will call the type of the first parameter the extended type of the method. It’s notofficial specification term<strong>in</strong>ology, but it’s a useful piece of shorthand.Not only does the previous list provide all the restrictions, but it also gives thedetails of what you need to do to turn a “normal” static method <strong>in</strong> a static class <strong>in</strong>to anLicensed to Rhona Hadida

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!