Free mag vol1 | Page 521

CHAPTER 12  LINQ TO OBJECTS foreach (Car c in onlyFastBMWs) { Console.WriteLine("{0} is going {1} MPH", c.PetName, c.Speed); } Projecting New Data Types It is also possible to project new forms of data from an existing data source. Let’s assume that you want to take the incoming ProductInfo[] parameter and obtain a result set that accounts only for the name and description of each item. To do so, you can define a select statement that dynamically yields a new anonymous type: static void GetNamesAndDescriptions(ProductInfo[] products) { Console.WriteLine("Names and Descriptions:"); var nameDesc = from p in products select new { p.Name, p.Description }; foreach (var item in nameDesc) { // Could also use Name and Description properties directly. Console.WriteLine(item.ToString()); } } Always remember that when you have a LINQ query that makes use of a projection, you have no way of knowing the underlying data type, as this is determined at compile time. In these cases, the var keyword is mandatory. As well, recall that you cannot create methods with implicitly typed return values. Therefore, the following method would not compile: static var GetProjectedSubset(ProductInfo[] products) { var nameDesc = from p in products select new { p.Name, p.Description }; return nameDesc; // Nope! } When you need to return projected data to a caller, one approach is to transform the query result into a .NET System.Array object using the ToArray() extension method. Thus, if you were to update your query expression as follows: // Return value is now an Array. static Array GetProjectedSubset(ProductInfo[] products) { var nameDesc = from p in products select new { p.Name, p.Description }; } // Map set of anonymous objects to an Array object. return nameDesc.ToArray(); you could invoke and process the data from Main() as follows: Array objs = GetProjectedSubset(itemsInStock); foreach (object o in objs) { Console.WriteLine(o); // Calls ToString() on each anonymous object. 461