Delegates, events and lambdas
Delegates
The declaration of a delegate type is similar to a method signature. It has a return value and any number of parameters of any type:
A delegate
is a reference type that can be used to encapsulate a named or an anonymous method. Delegates are similar to function pointers in C++; however, delegates are type-safe and secure.
Delegates are used to pass methods as arguments to other methods. Event handlers are nothing more than methods that are invoked through delegates.This ability to refer to a method as a parameter makes delegates ideal for defining callback methods.
Any method from any accessible class or struct that matches the delegate type can be assigned to the delegate. The method can be either static or an instance method. This makes it possible to programmatically change method calls, and also plug new code into existing classes.
Delegates have the following properties:
Delegates are similar to C++ function pointers, but delegates are fully object-oriented, and unlike C++ pointers to member functions, delegates encapsulate both an object instance and a method.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate type exactly.
C# version 2.0 introduced the concept of
Anonymous Methods
, which allow code blocks to be passed as parameters in place of a separately defined method. C# 3.0 introduced lambda expressions as a more concise way of writing inline code blocks. Both anonymous methods and lambda expressions (in certain contexts) are compiled to delegate types. Together, these features are now known as anonymous functions. For more information about lambda expressions, seeAnonymous Functions
.
Delegates are the basis for Events
.
Events
Events enable a class or object to notify other classes or objects when something of interest occurs. The class that sends (or raises) the event is called the publisher and the classes that receive (or handle) the event are called subscribers.
Events have the following properties:
The publisher determines when an event is raised; the subscribers determine what action is taken in response to the event.
An event can have multiple subscribers. A subscriber can handle multiple events from multiple publishers.
Events that have no subscribers are never raised.
Events are typically used to signal user actions such as button clicks or menu selections in graphical user interfaces.
When an event has multiple subscribers, the event handlers are invoked synchronously when an event is raised.
In the .NET Framework class library, events are based on the
EventHandler
delegate and theEventArgs
base class.
Lambdas
A lambda expression is a block of code (an expression or a statement block) that is treated as an object. It can be passed as an argument to methods, and it can also be returned by method calls. Lambda expressions are used extensively for:
You also can assign a lambda expression to an expression tree type:
Or you can pass it directly as a method argument:
Expression lambdas
The parentheses are optional only if the lambda has one input parameter; otherwise they are required.
Specify zero input parameters with empty parentheses:C#Copy
Two or more input parameters are separated by commas enclosed in parentheses:C#Copy
Sometimes it's impossible for the compiler to infer the input types. You can specify the types explicitly as shown in the following example:C#Copy
Statement lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces:
The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.
Statement lambdas, like anonymous methods, cannot be used to create expression trees.
Async lambdas
Lambda expressions and tuples
You define a tuple by enclosing a comma-delimited list of its components in parentheses. The following example uses tuple with three components to pass a sequence of numbers to a lambda expression, which doubles each value and returns a tuple with three components that contains the result of the multiplications.
Ordinarily, the fields of a tuple are named Item1
, Item2
, etc. You can, however, define a tuple with named components, as the following example does.
Last updated