Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

7.15.3Разрешение перегрузки

Анонимные функции в списке аргументов участвуют в выводе типа и разрешении перегрузки. Подробные правила см. в разделе §7.4.2.3.

В следующем примере демонстрируется результат использования анонимных функций при разрешении перегрузки

class ItemList<T>: List<T> { public int Sum(Func<T,int> selector) { int sum = 0; foreach (T item in this) sum += selector(item); return sum; }

public double Sum(Func<T,double> selector) { double sum = 0; foreach (T item in this) sum += selector(item); return sum; } }

У класса ItemList<T> есть два метода Sum. У каждого метода есть аргумент selector, который извлекает значение для суммирования из списка элементов. Извлеченное значение может иметь тип int или double, и сумма в результате также может иметь тип int или double.

Методы Sum можно, например, использовать для вычисления сумм из списка строк с деталями заказов.

class Detail { public int UnitCount; public double UnitPrice; ... }

void ComputeSums() { ItemList<Detail> orderDetails = GetOrderDetails(...); int totalUnits = orderDetails.Sum(d => d.UnitCount); double orderTotal = orderDetails.Sum(d => d.UnitPrice * d.UnitCount); ... }

В первом вызове orderDetails.Sum оба метода Sum применимы, поскольку анонимная функция d => d.UnitCount совместима и с Func<Detail,int> и с Func<Detail,double>. Однако при разрешении перегрузки будет выбран первый метод Sum, потому что преобразование в Func<Detail,int> оказывается лучше преобразования в Func<Detail,double>.

Во втором вызове orderDetails.Sum применим только второй метод Sum, потому что анонимная функция d => d.UnitPrice * d.UnitCount возвращает значение типа double. Поэтому в данном вызове при разрешении перегрузки будет выбран второй метод Sum.

7.15.4Анонимные функции и динамическая привязка

Анонимная функция не может быть получателем, аргументом или операндом динамически привязанной операции.

7.15.5Внешние переменные

Любая локальная переменная, параметр значения или массив параметров, область действия которого включает лямбда_выражение или выражение_анонимного_метода, называется внешней переменной анонимной функции. В функции-члене экземпляра для класса значение this считается параметром значения и является внешней переменно любой анонимной функции, содержащейся в функции-члене.

7.15.5.1Захваченные внешние переменные

Когда анонимная функция ссылается на внешнюю переменную, внешнюю переменную называют захваченной анонимной функцией. Обычно срок жизни локальной переменной ограничен выполнением блока или оператора, с которым она связана (§5.1.7). Однако срок жизни захваченной внешней переменной увеличивается по крайней мере до того, как делегат или дерево выражения, созданное из анонимной функции, становится объектом для процесса сборки мусора.

В примере

using System;

delegate int D();

class Test { static D F() { int x = 0; D result = () => ++x; return result; }

static void Main() { D d = F(); Console.WriteLine(d()); Console.WriteLine(d()); Console.WriteLine(d()); } }

локальная переменная x захватывается анонимной функцией и ее срок жизни увеличивается по крайней до тех пор, пока делегат, возвращенный из F, не станет объектом для процесса сборки мусора (что произойдет только в самом конце программы). Поскольку каждый вызов анонимной функции работает с одним экземпляром x, пример имеет следующий вывод:

1 2 3

Когда локальная переменная или параметр значения захватывается анонимной функцией, локальная переменная или параметр больше не считается фиксированной переменной (§18.3), а вместо этого считается перемещаемой переменной. Поэтому в любом небезопасном коде, который получает адрес захваченной внешней переменной, сначала необходимо использовать оператор fixed, чтобы зафиксировать переменную.

Заметьте, в отличие от незахваченной переменной, захваченная локальная переменная может быть одновременно использоваться в нескольких потоках выполнения.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]