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