Anonymous types
When coding an application you quite often will need to handle structured data
using some sort of temporary data structure. Traditionally you would declare a
new struct or class which can then be used as required. An anonymous type is one
which is created 'dynamically' in code, though in reality the compiler generates
a strictly typed class from it. For example, suppose we want to return just the
Title and ISBN from a query for Luke Rhinehart books. Rather than returning a
list of Book objects we could return a list of objects with just the two
required fields. The traditional approach would look like this:
public class BookName {
public string Title { get; set; }
public string ISBN { get; set; }
}
IEnumerable<BookName> lukesbooks = from book in books
where book.Author == "Luke Rhinehart"
select new BookName { Title = book.Title, ISBN = book.ISBN };
With an anonymous type we do not need to declare a class, or even declare the
return type in the query. The compiler can detemine, or infer, the types by the
context in which they are being used. The code now looks like this:
var lukesbooks = from book in books
where book.Author == "Luke Rhinehart"
select new { Title = book.Title, ISBN = book.ISBN };
The 'var' keyword is used to indicate to the compiler that it must determine the
appropriate type from the right hand side of the expression. The select
statement creates an anonymous type (note that the type name is missing from the
'new' statement) and so the return type will be an IEnumerable<anononymous
type>, where the anonymous type is a class with two string fields, Title and
ISBN. When we come to retrieve the data we can use the var keyword to specify
the object type in the return list of objects. For example:
var lukesbooks = from book in books
where book.Author == "Luke Rhinehart"
select new { Title = book.Title, ISBN = book.ISBN };
foreach (var lukebook in lukesbooks)
{
// do something with lukebook.Title and/or lukebook.ISBN
}
Note: the 'var' keyword does not have to be used with anonymous types, as
it can be used on the left hand side of a constructor statement for a defined
type. For example:
var book = new Book() { etc.};