Студопедия — Checked и unchecked 14 страница.
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Checked и unchecked 14 страница.






Методы 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, чтобы зафиксировать переменную.

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

7.15.5.2 Создание экземпляров локальных переменных

Считается, что для локальной переменной создается экземпляр, когда выполнение входит в область действия переменной. Например, при вызове следующего метода экземпляр локальной переменной x создается и инициализируется три раза, один раз для каждой итерации цикла.

static void F() {
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
...
}
}

Однако если перенести объявления x за пределы цикла, то экземпляр x будет создаваться только один раз.

static void F() {
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
...
}
}

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

В примере

using System;

delegate void D();

class Test
{
static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
int x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}

static void Main() {
foreach (D d in F()) d();
}
}

дает на выходе:

1
3
5

Однако при переносе объявления x за пределы цикла:

static D[] F() {
D[] result = new D[3];
int x;
for (int i = 0; i < 3; i++) {
x = i * 2 + 1;
result[i] = () => { Console.WriteLine(x); };
}
return result;
}

вывод имеет вид:

5
5
5

Если в цикле for объявляется переменная итерации, то сама эта переменная считается объявленной за пределами цикла. Таким образом, если изменить пример, чтобы захватывать саму переменную итерации

static D[] F() {
D[] result = new D[3];
for (int i = 0; i < 3; i++) {
result[i] = () => { Console.WriteLine(i); };
}
return result;
}

то будет захвачен только один экземпляр переменной итерации. В этом случае вывод имеет вид

3
3
3

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

static D[] F() {
D[] result = new D[3];
int x = 0;
for (int i = 0; i < 3; i++) {
int y = 0;
result[i] = () => { Console.WriteLine("{0} {1}", ++x, ++y); };
}
return result;
}

то три делегата будут захватывать один экземпляр x, но разные экземпляры y. Вывод будет иметь вид:

1 1
2 1
3 1

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

using System;

delegate void Setter(int value);

delegate int Getter();

class Test
{
static void Main() {
int x = 0;
Setter s = (int value) => { x = value; };
Getter g = () => { return x; };
s(5);
Console.WriteLine(g());
s(10);
Console.WriteLine(g());
}
}

две анонимные функции захватывают один экземпляр локальной переменной x и поэтому они могут «взаимодействовать» через эту переменную. Вывод в данном примере имеет вид:

5
10

7.15.6 Вычисление выражений анонимных функций

Анонимная функция F всегда должна преобразовываться в тип делегата D или тип дерева выражения E либо напрямую, либо с помощью выполнения выражения создания делегата new D(F). Это преобразование определяет результат анонимной функции, как описано в разделе §6.5.

7.16 Выражения запросов;

Выражения запросов представляют собой подмножество синтаксических конструкций языка для запросов, похожих запросы иерархических или реляционных языков запросов, таких как SQL и XQuery.







Дата добавления: 2015-09-07; просмотров: 424. Нарушение авторских прав; Мы поможем в написании вашей работы!



Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Теория усилителей. Схема Основная масса современных аналоговых и аналого-цифровых электронных устройств выполняется на специализированных микросхемах...

Логические цифровые микросхемы Более сложные элементы цифровой схемотехники (триггеры, мультиплексоры, декодеры и т.д.) не имеют...

Расчет концентрации титрованных растворов с помощью поправочного коэффициента При выполнении серийных анализов ГОСТ или ведомственная инструкция обычно предусматривают применение раствора заданной концентрации или заданного титра...

Психолого-педагогическая характеристика студенческой группы   Характеристика группы составляется по 407 группе очного отделения зооинженерного факультета, бакалавриата по направлению «Биология» РГАУ-МСХА имени К...

Общая и профессиональная культура педагога: сущность, специфика, взаимосвязь Педагогическая культура- часть общечеловеческих культуры, в которой запечатлил духовные и материальные ценности образования и воспитания, осуществляя образовательно-воспитательный процесс...

Алгоритм выполнения манипуляции Приемы наружного акушерского исследования. Приемы Леопольда – Левицкого. Цель...

ИГРЫ НА ТАКТИЛЬНОЕ ВЗАИМОДЕЙСТВИЕ Методические рекомендации по проведению игр на тактильное взаимодействие...

Реформы П.А.Столыпина Сегодня уже никто не сомневается в том, что экономическая политика П...

Studopedia.info - Студопедия - 2014-2024 год . (0.012 сек.) русская версия | украинская версия