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.

252 CHAPTER 9 Lambda expressions and expression treesWhen there are multiple parameters, the compiler has to make sure there isexactly one method that is at least as good as all the others for every parameter. As asimple example, suppose we hadvoid Write(<strong>in</strong>t x, double y)void Write(double x, <strong>in</strong>t y)A call to Write(1, 1) would be ambiguous, and the compiler would force you to add acast to at least one of the parameters to make it clear which method you meant to call.That logic still applies to <strong>C#</strong> 3, but with one extra rule about anonymous functions,which never specify a return type. In this case, the <strong>in</strong>ferred return type (as described<strong>in</strong> 9.4.2) is used <strong>in</strong> the “better conversion” rules.Let’s see an example of the k<strong>in</strong>d of situation that needs the new rule. List<strong>in</strong>g 9.16conta<strong>in</strong>s two methods with the name Execute, and a call us<strong>in</strong>g a lambda expression.List<strong>in</strong>g 9.16Sample of overload<strong>in</strong>g choice <strong>in</strong>fluenced by delegate return typestatic void Execute(Func action){Console.WriteL<strong>in</strong>e("action returns an <strong>in</strong>t: "+action());}static void Execute(Func action){Console.WriteL<strong>in</strong>e("action returns a double: "+action());}...Execute( () => 1 );The call to Execute <strong>in</strong> list<strong>in</strong>g 9.16 could have been written with an anonymous methodor a method group <strong>in</strong>stead—the same rules are applied whatever k<strong>in</strong>d of conversion is<strong>in</strong>volved. So, which Execute method should be called? The overload<strong>in</strong>g rules say thatwhen two methods are both applicable after perform<strong>in</strong>g conversions on the arguments,then those argument conversions are exam<strong>in</strong>ed to see which one is “better.” The conversionshere aren’t from a normal .NET type to the parameter type—they’re from alambda expression to two different delegate types. So, which conversion is better?Surpris<strong>in</strong>gly enough, the same situation <strong>in</strong> <strong>C#</strong> 2 would result <strong>in</strong> a compilationerror—there was no language rule cover<strong>in</strong>g this case. In <strong>C#</strong> 3, however, the methodwith the Func parameter would be chosen. The extra rule that has been addedcan be paraphrased to this:If an anonymous function can be converted to two delegate types that havethe same parameter list but different return types, then the delegateconversions are judged by the conversions from the <strong>in</strong>ferred return type tothe delegates’ return types.That’s pretty much gibberish without referr<strong>in</strong>g to an example. Let’s look back at list<strong>in</strong>g9.16: we’re convert<strong>in</strong>g from a lambda expression with no parameters and an<strong>in</strong>ferred return type of <strong>in</strong>t to either Func or Func. The parameter listsare the same (empty) for both delegate types, so the rule applies. We then just need toLicensed to Rhona Hadida

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

Saved successfully!

Ooh no, something went wrong!