This course will be retired on July 14, 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
Well done!
You have completed Querying With LINQ!
You have completed Querying With LINQ!
Preview
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