Tuples are popular choices in other programming languages for tightly-scoped data containers. One drawbacks of tuples is that items within the tuple are referenced by a numerical position rather than a name much like an array.
Anonymous types give some of the convenience of tuples but with the ability to name the items contained within it. The trade-offs are that each anonymous type is independent and is not interchangeable with other types even when they have an identical definition and that the type has no name you can refer to directly (but you can indirectly using generics).3
Code
var contacts = db.Customers.Select(c => new { c.Name, c.Email });
foreach (var contact in contacts)
Console.WriteLine(contact.Name + "\t" + contact.Email);
var contacts = db.Customers.Select(c => new Contact { Name = c.Name, Email = c.Email });
foreach (var contact in contacts)
Console.WriteLine(contact.Name + "\t" + contact.Email);
// ...
class Contact
{
string Name;
string Email;
}
Notes
- The compiler will create a class named
<>c
and put your anonymous method there - Anonymous types are often used in LINQ
Select
statements to "project" a final structure:
1 LINQ providers only understand the query and the lambda expressions. Using this kind of projection tells them what fields they need to retrieve (they can not look at other code as it is compiled).
2 You can project into other classes but really only as the last operation in the query. Some providers can follow the assignment through other classes mid-query if you use initializer syntax but many do not. Using a constructor mid-query will almost certainly fail or result in wrong behavior.
3 If you want that behavior you can always use Tuple.Create
which share types between identical structures at the expense of giving up names for Item1
, Item2
etc. Alternatively you can make your method generic and have the parameter be the generic type - the runtime will take care of ensuring the method is created with the correct anonymous declaration.