When querying with linq the background compiler automatically infers type information from any implementation of IEnumerable<T> as IEnumerable<anonymous type>. This gives us the IntelliSense we know and love while writing a query against a known type, without being bound to query results of which are of that type. Instead we can project onto new known types, new anonymous types, or in this case, a sub type.
Consider the following class:
public class Person
{
public string Name { get; set; }
}
A list:
List<Person> persons = new List<Person>()
{
new Person { Name="Bob" },
new Person { Name="Nancy" },
};
var query = from p in persons
where p.Name == "Bob"
select p;
In this query, only one expression has been selected, so our var query has inferred the type Person from the List<Person> implementation of IEnumerable<T>. Our IntelliSense for p looks like this:
Now lets add some inheritance:
public class Employee : Person
{
public bool IsActive { get; set; }
public string Dept { get; set; }
}
Some new Employees to our list:
List<Person> persons = new List<Person>()
{
new Person { Name="Bob" },
new Person { Name="Nancy" },
new Employee { Name="Sam", IsActive=true, Dept="Sales" },
new Employee { Name="Alice", IsActive=false, Dept="Accounting" }
};
Hmm, now how do I select Employees who are active and work in sales if my IntelliSense is being driven off List<Person>?
Well, we can certainly use standard C# operators to get the job done:
var query = from p in persons
where p is Employee &&
(p as Employee).Dept == "Sales" &&
(p as Employee).IsActive == true
select p as Employee;
var query = from p in persons.OfType<Employee>()
where p.Dept == "Sales" &&
p.IsActive == true
select p;