13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

246 CHAPTER 9 Lambda expressions and expression treesEven with<strong>in</strong> this section I’m not go<strong>in</strong>g to go <strong>in</strong>to absolutely every nook andcranny—that’s what the language specification is for. Instead, I’ll give an overview ofthe new behavior, provid<strong>in</strong>g examples of common cases. The primary reason forchang<strong>in</strong>g the specification is to allow lambda expressions to work <strong>in</strong> a concise fashion,which is why I’ve <strong>in</strong>cluded the topic <strong>in</strong> this particular chapter. Let’s look a little deeperat what problems we’d have run <strong>in</strong>to if the <strong>C#</strong> team had stuck with the old rules.9.4.1 Reasons for change: streaml<strong>in</strong><strong>in</strong>g generic method callsType <strong>in</strong>ference occurs <strong>in</strong> a few situations. We’ve already seen it apply to implicitlytyped arrays, and it’s also required when you try to implicitly convert a method groupto a delegate type as the parameter to a method—with overload<strong>in</strong>g of the methodbe<strong>in</strong>g called, and overload<strong>in</strong>g of methods with<strong>in</strong> the method group, and the possibilityof generic methods gett<strong>in</strong>g <strong>in</strong>volved, the set of potential conversions can becomequite overwhelm<strong>in</strong>g.By far the most common situation for type <strong>in</strong>ference is when you’re call<strong>in</strong>g ageneric method without specify<strong>in</strong>g the type arguments for that method. This happensall the time <strong>in</strong> LINQ—the way that query expressions work depends on this heavily. It’sall handled so smoothly that it’s easy to ignore how much the compiler has to workout on your behalf, all for the sake of mak<strong>in</strong>g your code clearer and more concise.The rules were reasonably straightforward <strong>in</strong> <strong>C#</strong> 2, although method groups andanonymous methods weren’t always handled as well as we might have liked. The type<strong>in</strong>ference process didn’t deduce any <strong>in</strong>formation from them, lead<strong>in</strong>g to situationswhere the desired behavior was obvious to developers but not to the compiler. Life ismore complicated <strong>in</strong> <strong>C#</strong> 3 due to lambda expressions—if you call a generic methodus<strong>in</strong>g a lambda expression with an implicitly typed parameter list, the compiler needsto work out what types you’re talk<strong>in</strong>g about, even before it can check the lambdaexpression’s body.This is much easier to see <strong>in</strong> code than <strong>in</strong> words. List<strong>in</strong>g 9.11 gives an example of thek<strong>in</strong>d of issue we want to solve: call<strong>in</strong>g a generic method us<strong>in</strong>g a lambda expression.List<strong>in</strong>g 9.11Example of code requir<strong>in</strong>g the new type <strong>in</strong>ference rulesstatic void Pr<strong>in</strong>tConvertedValue(TInput <strong>in</strong>put, Converter converter){Console.WriteL<strong>in</strong>e(converter(<strong>in</strong>put));}...Pr<strong>in</strong>tConvertedValue("I'm a str<strong>in</strong>g", x => x.Length);The method Pr<strong>in</strong>tConvertedValue <strong>in</strong> list<strong>in</strong>g 9.11 simply takes an <strong>in</strong>put value and adelegate that can convert that value <strong>in</strong>to a different type. It’s completely generic—itmakes no assumptions about the type parameters TInput and TOutput. Now, look atthe types of the arguments we’re call<strong>in</strong>g it with <strong>in</strong> the bottom l<strong>in</strong>e of the list<strong>in</strong>g. Thefirst argument is clearly a str<strong>in</strong>g, but what about the second? It’s a lambda expression,so we need to convert it <strong>in</strong>to a Converter—and that means weneed to know the types of TInput and TOutput.Licensed to Rhona Hadida

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

Saved successfully!

Ooh no, something went wrong!