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.

288 CHAPTER 11 Query expressions and LINQ to Objectsbecomes easier to understand a query expression that has a slightly more complicatedprojection. List<strong>in</strong>g 11.4 pr<strong>in</strong>ts out just the names of our users.List<strong>in</strong>g 11.4Query select<strong>in</strong>g just the names of the usersvar query = from user <strong>in</strong> SampleData.AllUsersselect user.Name;foreach (str<strong>in</strong>g name <strong>in</strong> query){Console.WriteL<strong>in</strong>e(name);}This time we’re us<strong>in</strong>g user.Name as the projection, and we can see that the result is asequence of str<strong>in</strong>gs, not of User objects. The translation of the query expression followsthe same rules as before, and becomesSampleData.AllUsers.Select(user => user.Name)The compiler allows this, because the Select extension method as applied to AllUserseffectively has this signature, act<strong>in</strong>g as if it were a member of IEnumerable:IEnumerable Select (Func selector)NOTEExtension methods pretend<strong>in</strong>g to be <strong>in</strong>stance methods—Just to be clear, Selectisn’t a member of IEnumerable itself, and the real signature has anIEnumerable parameter at the start. However, the translation processdoesn’t care whether the result is a call to a normal <strong>in</strong>stance method oran extension method. I f<strong>in</strong>d it easier to pretend it’s a normal method justfor the sake of work<strong>in</strong>g out the query translation. I’ve used the same conventionfor the rema<strong>in</strong>der of the chapter.The type <strong>in</strong>ference described <strong>in</strong> chapter 9 kicks <strong>in</strong>, convert<strong>in</strong>g the lambda expression<strong>in</strong>to a Func by decid<strong>in</strong>g that the user parameter must be of type User,and then <strong>in</strong>ferr<strong>in</strong>g that the return type (and thus TResult) should be str<strong>in</strong>g. This iswhy lambda expressions allow implicitly typed parameters, and why there are suchcomplicated type <strong>in</strong>ference rules: these are the gears and pistons of the LINQ eng<strong>in</strong>e.NOTE Why do you need to know all this? You can almost ignore what’s go<strong>in</strong>g onwith range variables for a lot of the time. You may well have seen many,many queries and understood what they achieve without ever know<strong>in</strong>gabout what’s go<strong>in</strong>g on beh<strong>in</strong>d the scenes. That’s f<strong>in</strong>e for when th<strong>in</strong>gs arework<strong>in</strong>g (as they tend to with examples <strong>in</strong> tutorials), but it’s when th<strong>in</strong>gsgo wrong that it pays to know about the details. If you have a queryexpression that won’t compile because the compiler is compla<strong>in</strong><strong>in</strong>g thatit doesn’t know about a particular identifier, you should look at the rangevariables <strong>in</strong>volved.So far we’ve only seen implicitly typed range variables. What happens when we<strong>in</strong>clude a type <strong>in</strong> the declaration? The answer lies <strong>in</strong> the Cast and OfType standardquery operators.Licensed to Rhona Hadida

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

Saved successfully!

Ooh no, something went wrong!