Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
16
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Анонимные методы

Именованные методы были единственным способом объявления делегата в версиях C#, предшествующих версии 2.0. Анонимные методы были представлены в C# 2.0, а в версиях C# 3.0 и более поздних лямбда-выражения заменяют эти методы и являются предпочтительным способом написания встроенного кода. Однако сведения об анонимных методах, представленные в данном разделе, применяются и к лямбда-выражениям. Существует только один случай, в котором функциональность анонимного метода отсутствует в лямбда-выражениях. Анонимные методы позволяют отказаться от использования списка параметров, а это значит, что анонимный метод может быть преобразован в делегаты с различными подписями. Это невозможно в ситуации с лямбда-выражениями. Дополнительные сведения именно о лямбда-выражениях см. в разделе Лямбда-выражения.

Создание анонимных методов является, по существу, способом передачи блока кода в качестве параметра делегата. Далее представлено два примера.

---

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

Например, указание блока кода вместо делегата может быть целесообразно в ситуации, когда создание метода может показаться ненужным действием. Хорошим примером является запуск нового потока. Этот класс создает поток и содержит код, выполняемый потоком без создания дополнительного метода для его делегата.

---

Remarks

The scope of the parameters of an anonymous method is the anonymous-method-block.

It is an error to have a jump statement, such as goto, break, or continue, inside the anonymous method block if the target is outside the block. It is also an error to have a jump statement, such as goto, break, or continue, outside the anonymous method block if the target is inside the block.

The local variables and parameters whose scope contains an anonymous method declaration are called outer variables of the anonymous method. For example, in the following code segment, n is an outer variable:

int n = 0;

Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

Unlike local variables, the lifetime of the captured variable extends until the delegates that reference the anonymous methods are eligible for garbage collection. A reference to n is captured at the time the delegate is created.

An anonymous method cannot access the ref or out parameters of an outer scope.

No unsafe code can be accessed within the anonymous-method-block.

Anonymous methods are not allowed on the left side of the is operator.

Заметки

Областью действия параметров анонимного метода является блок анонимного метода.

Если целевой объект находится вне блока, то наличие оператора перехода, например goto, break или continue, в блоке анонимного метода будет ошибкой. Если целевой объект находится внутри блока, то наличие оператора перехода, например goto, break или continue, вне блока анонимного метода также будет ошибкой.

Локальные переменные и параметры, область действия которых содержит объявление анонимного метода, называются внешними переменными анонимного метода. Например, в следующем сегменте кода n является внешней переменной.

int n = 0;

Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };

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

Анонимный метод не может обращаться к параметрам ref или out внешней области действия.

В блоке анонимного метода нельзя получить доступ ни к одному небезопасному коду.

Анонимные методы не разрешены с левой стороны оператора is.

Example

The following example demonstrates two ways of instantiating a delegate:

  • Associating the delegate with an anonymous method.

  • Associating the delegate with a named method (DoWork).

In each case, a message is displayed when the delegate is invoked.

// Declare a delegate

delegate void Printer(string s);

class TestClass

{

static void Main()

{

// Instatiate the delegate type using an anonymous method:

Printer p = delegate(string j)

{

System.Console.WriteLine(j);

};

// Results from the anonymous delegate call:

p("The delegate using the anonymous method is called.");

// The delegate instantiation using a named method "DoWork":

p = new Printer(TestClass.DoWork);

// Results from the old style delegate call:

p("The delegate using the named method is called.");

}

// The method associated with the named delegate:

static void DoWork(string k)

{

System.Console.WriteLine(k);

}

}

Output

The delegate using the anonymous method is called.

The delegate using the named method is called.

Пример

В следующем примере представлено два способа создания делегата.

  • Связывание делегата с анонимным методом.

  • Связывание делегата с именованным методом (DoWork).

В каждом случае при вызове делегата отображается сообщение.

----

Overloadable Operators

C# allows user-defined types to overload operators by defining static member functions using the operator keyword. Not all operators can be overloaded, however, and others have restrictions, as listed in this table:

Operators

Overloadability

+, -, !, ~, ++, --, true, false

These unary operators can be overloaded.

+, -, *, /, %, &, |, ^, <<, >>

These binary operators can be overloaded.

==, !=, <, >, <=, >=

The comparison operators can be overloaded (but see the note that follows this table).

&&, ||

The conditional logical operators cannot be overloaded, but they are evaluated using & and |, which can be overloaded.

[]

The array indexing operator cannot be overloaded, but you can define indexers.

()

The cast operator cannot be overloaded, but you can define new conversion operators (see explicit and implicit).

+=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=

Assignment operators cannot be overloaded, but +=, for example, is evaluated using +, which can be overloaded.

=, ., ?:, ->, new, is, sizeof, typeof

These operators cannot be overloaded.

Note:

The comparison operators, if overloaded, must be overloaded in pairs; that is, if == is overloaded, != must also be overloaded. The reverse is also true, and similar for < and >, and for <= and >=.

To overload an operator on a custom class requires creating a method on the class with the correct signature. The method must be named "operator X" where X is the name or symbol of the operator being overloaded. Unary operators have one parameter, and binary operators have two parameters. In each case, one parameter must be the same type as the class or struct that declares the operator, as demonstrated in the following example:

public static Complex operator +(Complex c1, Complex c2)

For more information, see How to: Use Operator Overloading to Create a Complex Number Class.