This course will be retired on June 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Learn about using projection and anonymous types when writing LINQ queries.
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
Just in case you took a break before this
video where we built a list of birds,
0:00
we're going to load up a list
of birds using the BirdWatcher
0:05
assembly file in our workspace.
0:07
There's a readme file with instructions
to load it in your REPL so
0:10
we can get our list of birds back.
0:13
csharp.
0:16
LoadAssembly BirdWatcher.dll.
0:17
Using BirdWatcher, which is our namespace.
0:29
And List of Bird birds =
0:35
BirdRepository.LoadBirds(); and
0:40
there's our birds.
0:48
Our bird repository has a static method
that will retrieve bird data for us.
0:52
If you haven't seen something
called a repository before,
0:57
it's a part of a design pattern
called the repository pattern.
0:59
Really, all it means is that we can get
data from it without having to worry about
1:03
where or how to retrieve it.
1:06
If you want to read more
about the repository pattern,
1:09
check out the notes for some resources.
1:12
Another feature I wanna show you
before we get back to querying
1:15
is called implicit typing.
1:18
You might have already seen it.
1:20
We can use the var keyword instead
of declaring a type for a variable.
1:22
var canary = new
1:26
Bird Name = Canary,
1:31
Color = Yellow, and
1:37
Sightings = 0.
1:42
The compiler infers the type from
the right side of the assignment operator,
1:49
which in this case is a bird.
1:54
Let's add the canary
to our birds list too.
1:56
birds.Add(canary).
1:59
It's also really easy to
use in a foreach loop.
2:06
The compiler knows what type
is in our birds list, so
2:09
we can rewrite our earlier loop statement.
2:12
foreach var bird in birds.
2:15
Console.WriteLine bird.Name.
2:23
We'll be using the var keyword
a lot while writing LINQ queries.
2:35
Sometimes you might even have to use it
when you're dealing with types that won't
2:39
be known until compiling.
2:42
Let's get back to querying with LINQ and
2:44
learn about a couple of
other LINQ keywords.
2:46
Now that we've got a list of Bird objects,
2:49
let's write a query to get
all birds that are red.
2:51
from b in birds where to b.Color = Red,
2:54
and that is case sensitive, select b.
3:02
That returned a collection
of Bird objects.
3:12
We can use the select clause
to return properties instead.
3:15
Let's get just the names.
3:19
from b in birds where
3:21
b.Color == Red,
3:26
select b.Name.
3:31
That returned a new enumerable of strings
that contains the name of the birds that
3:36
are the color red.
3:40
We can also select more than
one property into a new type.
3:43
from b in birds
3:47
where b.Color
3:51
== Red select
3:56
new b.Name and
4:01
b.Color.
4:06
So what do you think that returns?
4:10
We haven't told it what we want
to create after the new keyword.
4:12
This is called projection in LINQ, and
4:16
we're projecting the results of
the LINQ query to an anonymous type.
4:19
Anonymous types are another one of those
neat features that came along with
4:24
LINQ to support it.
4:27
It's like creating a new type on the fly.
4:28
At compile time, the compiler is
actually creating a new type for it.
4:31
It's called an anonymous type
because it doesn't have a name.
4:36
We can also specify different property
names if we want inside the curly braces.
4:39
From b in birds where
4:45
b.Color = Red select new,
4:50
open curly brace,
4:57
{ BirdName = b.Name and
5:01
BirdColor = b.Color };.
5:07
So the result of that query is
two anonymously typed objects in
5:14
an enumerable with the properties
BirdName and BirdColor.
5:19
We can even create an anonymously
typed object by using the var keyword.
5:24
var anonymousPidgeon = new,
5:29
open curly brace, Name = Pigeon,
5:34
Color = White for the most part,
5:41
and sightings = 10.
5:46
So in this case,
we actually have to use the var keyword,
5:54
since we don't know what
the type is until compile time.
5:58
And if I create another anonymously typed
6:01
object with the same exact properties,
6:06
var anonymousCrow = new { Name = crow,
6:12
Color =, whoops, let's try that again.
6:17
var anonymousCrow =
6:23
new { Name = Crow,
6:28
Color = Black, and
6:33
Sightings = 11.
6:38
The compiler recognizes that it has
an anonymous type with the same
6:43
properties and in the same order, so
it's actually assigning the same type.
6:47
Let's see if it is.
6:52
anonymousCrow.GetType() ==
6:54
anonymousPidgeon.GetType() and it's true.
7:00
But even though the anonymous type has
the same properties in our Bird class,
7:11
we won't be able to add it to
our bird list by calling add.
7:16
.Add(anonymousCrow).
7:19
We need to access the properties
of the anonymous type and
7:24
create a new bird manually, like this.
7:28
birds.Add(new Bird {
7:31
Name = anonymousCrow.Name,
7:36
Color = anonymousCrow.Color,
7:43
and Sightings =
7:51
anonymousCrow.Sightings)}.
7:55
Anonymous types can be
really useful in LINQ and
8:03
we'll be using them a lot in this course.
8:05
There are other limitations
to anonymous types, though.
8:08
You can't really pass anonymous types
to other methods without some reverse
8:10
engineering.
8:14
Also, the properties are read
only after you create them.
8:15
They are really only useful for
8:19
quick, temporary storage to
hold data in a small scope.
8:20
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up