¨ Для прохода вдоль последовательности g, имеющей тип IGrouping<int,int>, также необходимо привести ее к типу Array. Это также делает extension-метод ToArray.
¨ Первая лямбда-операция (читай — код делегата) имеет более сложный вид, чем вторая. Блок кода, реализующий ее, содержит вложенную лямбда-операцию y => Console.Write(y + ", ").
Лямбда-выражения могут быть составными. Следующий пример показывает, что λ-выражение с двумя параметрами эквивалентно последовательности двух λ-выражений с одним параметром.
Console.Write("\nTest (x, y) => x + y: ");
Func<int, int, int> lambda = (x, y) => x + y;
Console.WriteLine (lambda(3, 4));
Func<int, Func<int, int>> curry = x => y => x + y;
Console.Write ("Test x => y => x + y: ");
Console.WriteLine (curry(3)(4));
Мы убедились, что источником данных для LINQ-запроса может быть любая коллекция, реализующая интерфейс IEnumerable<T>. Но им также может быть и любой объект, реализующий интерфейс IQueryable<T>.
public interface IQueryable<out T> : IEnumerable<T>, IQueryable, IEnumerable
Параметр T является ковариантным. Это означает, что вместо типа T вы можете подать и любой из типов, производных от T. Типы, реализующие IQueryable<T>, не являются коллекциями. Они представляют собой описания запросов, которые генерируются динамически и поддерживают полиморфизм и оптимизацию. Такие типы, совместно с деревьями выражений (expression trees) допускают компиляцию запросов с целью повышения производительности, и могут служить входными данными для образования других LINQ-запросов.
Интерфейс IQueryable (так же как и IEnumerable) задает сигнатуру только одного метода.
IEnumerator GetEnumerator()
Интерфейс IQueryProvider определяет методы, необходимые для создания и исполнения запросов, определенных IQueryable-типом. Интерфейс IQueryProvider задает сигнатуру двух методов:
IQueryable CreateQuery(Expression expression);
object Execute <TResult>(Expression)
Цепочка действий, которая выполняется при вызове метода Execute <TResult>(Expression) зависит от провайдера данных. Одним из вариантов реализации запроса может быть трансляция дерева выражения в текст запроса, удовлетворяющего синтаксису конкретного языка запросов. Конкретный язык запросов определяется провайдером данных.
Следующий пример показывает, как используются новые возможности C# 4.0 для управления объектами COM Interop. В частности для создания документов Microsoft Office (Excel и Word). Новые возможности (именованные параметры и индексируемые свойства) сильно упрощают общение с Office API.
using System;
using System.Collections.Generic;
using System.Drawing;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;
public class Account
{
public int ID { get; set; }
public double Balance { get; set; }
}
public class Program
{
static void Main()
{
var checkAccounts = new List<Account>
{
new Account { ID = 345, Balance = 541.27 },
new Account { ID = 123, Balance = -127.44 }
};
Action<Account, Excel.Range> display = (account, cell) =>
{
cell.Value = account.ID;
cell.Offset[0, 1].Value = account.Balance;
if (account.Balance < 0)
{
cell.Interior.Color = ColorTranslator.ToOle(Color.FromArgb(255,255,200));
cell.Offset[0, 1].Interior.Color = ColorTranslator.ToOle(Color.LightSkyBlue);
}
};
DisplayInExcel(checkAccounts, display);
var word = new Word.Application();
word.Visible = true;
word.Documents.Add();
word.Selection.PasteSpecial(Link: true, DisplayAsIcon: false);
}
public static void DisplayInExcel(IEnumerable<Account> accounts, Action<Account, Excel.Range> display)
{
var xl = new Excel.Application();
xl.Workbooks.Add();
xl.Visible = true;
xl.Cells[1, 1] = "ID";
xl.Cells[1, 2] = " Balance";
xl.Cells[2, 1].Select();
foreach (var ac in accounts)
{
display(ac, xl.ActiveCell);
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.