Let's start with LINQ to Objects. It enables you to use LINQ to directly query any IEnumerable
or IQueryable
collections (such as string[]
, int[]
, and List
) directly without needing to use an immediate LINQ provider or API such as the LINQ to SQL or LINQ to XML.
Say that you have a collection of data stored in an array, and you want to be able to retrieve a subset of the data quickly. In the old way of doing things, you write a loop and iteratively retrieve all the data that matches your criteria. That's time-consuming because you have to write all the logic to perform the comparison and so on. Using LINQ, you can declaratively write the condition using an SQL-like statement, and the compiler does the job of retrieving the relevant data for you.
Suppose that you have an array of type string that contains a list of names. The following program prints out all the names in the string array that start with the character G:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ {
class Program {
static void Main(string[] args) {
string[] allNames = new string[] {
"Jeffrey", "Kirby", "Gabriel",
"Philip", "Ross", "Adam",
"Alston", "Warren", "Garfield"
};
foreach (string str in allNames) {
if (str.StartsWith("G")) {
Console.WriteLine(str);
}
}
Console.ReadLine();
}
}
}
Using LINQ to Objects, you can rewrite the program as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace LINQ {
class Program {
static void Main(string[] args) {
string[] allNames = new string[] {
"Jeffrey", "Kirby", "Gabriel",
"Philip", "Ross", "Adam",
"Alston", "Warren", "Garfield"
};
IEnumerable foundNames =
from name in allNames
where name.StartsWith("G")
select name;
foreach (string str in foundNames)
Console.WriteLine(str);
Console.ReadLine();
}
}
}
Notice that you have declared the foundNames
variable to be of type IEnumerable
, and the expression looks similar to that of SQL:
IEnumerable foundNames =
from name in allNames
where name.StartsWith("G")
select name;
The one important difference from SQL queries is that in a LINQ query the operator sequence is reversed. In SQL, you use the select-from-where
format, while LINQ queries use the format from-where-select
. This reversal in order allows IntelliSense to know which data source you are using so that it can provide useful suggestions for the where
and select
clauses.
The result of the query in this case is IEnumerable
. You can also use the new implicit typing feature in C# 3.0 to let the C# compiler automatically infer the type for you, like this:
var foundNames =
from name in allNames
where name.StartsWith("G")
select name;
When you now use a foreach
loop to go into the foundNames
variable, it will contain a collection of names that starts with the letter G. In this case, it returns Gabriel
, Garfield
.
The usefulness of LINQ is more evident when you have more complex filters. For example:
var foundNames =
from name in allNames
where name.StartsWith("G") && name.EndsWith("l")
select name;
In this case, only names that begin with "G" and end with "l" will be retrieved ( Gabriel
).
Here's an example where you have an array of integer values. You want to retrieve all the odd numbers in the array and sort them in descending order (that is, the bigger numbers come before the smaller numbers). Using LINQ, your code looks like this:
int[] nums = {
12, 34, 10, 3, 45, 6, 90, 22, 87, 49, 13, 32
};
var oddNums = from n in nums
where (n % 2 == 1) orderby n descending
select n;
foreach (int n in oddNums)
Console.WriteLine(n);
And here's what the code will print out:
87
49
45
13
3
To find out the total number of odd numbers found by the query, you can use the Count()
method from the oddNums variable (of type IEnumerable
) :
int count = oddNums.Count();
You can also convert the result into an int array, like this:
int[] oddNumsArray = oddNums.ToArray();
Query Syntax versus Method Syntax and Lambda Expressions
The two LINQ queries in the previous section use the query syntax , which is written in a declarative manner, like this:
var oddNums = from n in nums
where (n % 2 == 1) orderby n descending
select n;
In addition to using the query syntax, you can also use the method syntax, which is written using method calls like Where
and Select
, like this:
int[] nums = {
12, 34, 10, 3, 45, 6, 90, 22, 87, 49, 13, 32
};
IEnumerable oddNums =
nums.Where(n => n % 2 == 1).OrderByDescending(n => n);
To find the total number of odd numbers in the array, you can also use the method syntax to query the array directly, like this:
int count =
(nums.Where(n => n % 2 == 1).OrderBy(n => n)).Count();
Читать дальше