Lecture 6: Powerpoint

advertisement
COMPSCI 280 S2 2015
Enterprise Software Development
Delegates and lambda functions
Jim Warren, jim@cs.auckland.ac.nz
Today’s learning objectives

To understand and be able to apply C# language features in a
variety of contexts for


2
Development of delegates
Use of lambda functions
COMPSCI 280
Delegates

Delegates are object-oriented, type-safe, and secure function
pointers





A delegate is a reference type that defines a method signature
A delegate instance holds one or more methods
Methods can be static or non-static
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
BOSS
Job
Finished???
Finished???
Call back when Finished


3
Delegates can be chained together; for example, multiple methods
can be called on a single event.
It is a foundation of event handling.
COMPSCI280
Creating Delegates

The type of a delegate is defined by the name of the delegate
public delegate void Print(string s);


Each delegate is limited to referencing methods of a particular kind only. The type is
indicated by the delegate declaration – the input parameters and return type
Example:

Two methods with the same signature as the delegate declared above
public static void printToLower (string s) {
Console.WriteLine("static: " + s.ToLower());
}
public void printToUpper (string s) {
Console.WriteLine("instance: " + s.ToUpper());
}

Static method
Creating a New Delegate Object




Use the new operator
The argument is the method call, but without the arguments to the method
Delegate objects are immutable. (can’t change)
A delegate can reference static or instance method
Print v1 = new Print(printToLower);
Print v2 = new Print(new Program().printToUpper );
4
COMPSCI280
Using Delegates

Once a delegate is instantiated, a method call made to the
delegate will be passed by the delegate to that method and will
call the underlying method

Use the name of the delegate, followed by the parenthesized arguments to
be passed to the delegate
Static method
output:
static: this is a test
v1("This is a test");
v2("This is a test");
5
COMPSCI280
output:
instance: THIS IS A TEST
Using Arrays




Create an array of delegate objects
Instantiate each delegate object with various instance methods
defined above
Note: In C#, if we reference a method on an object (omitting
the parentheses), C# instead treats the method name like a
field, returning the object representing that method.
Call each delegate object by using a loop -> invoke the
underlying method
public delegate void Print(string s);
Print[] arr = new Print[2];
arr[0] = new Print(printToLower);
arr[1] = new Print(new Program().printToUpper);
foreach (Print p in arr)
p("In an array");
static: in an array
instance: IN AN ARRAY
6
COMPSCI280
Named & Anonymous methods

Named Method

public delegate void Print(string s);
A delegate can be associated with a named method.

When you instantiate a delegate using a named method, the method is passed as a
parameter


The method that you pass as a delegate parameter must have the same signature as the
delegate declaration.
A delegate instance may encapsulate either a static or an instance method.
Named method
Print v1
v1("This
Print v2
v2("This

= printToLower;
is another test");
= new Program().printToUpper;
is another test");
Anonymous Method

In C# 2.0 (from 2005), you can declare a delegate using an anonymous
method
Print a1 = delegate(string j){
Anonymous
method
7
Console.WriteLine("Anonymous:" + j);
};
a1("Well done");
COMPSCI280
Multicast delegates


Delegate objects can be assigned to one delegate instance to be multicast using
the + operator.
A delegate can simultaneously reference multiple methods, and it will invoke all
underlying methods


Conditions:


Methods are invoked sequentially, in the order added.
Only delegates of the same type can be composed.
The - operator can be used to remove a component delegate from a
composed delegate.
public delegate void Print(string s);
A delegate
object
Print mp2 = null;
mp2 += printToLower;
mp2 += new Program().printToUpper;
mp2("Hello World");
Output:
static: hello world
Instance: HELLO WORLD
8
COMPSCI280
Event

Event Basic:






An event is a message sent by an object to signal the occurrence of an action.
The action could be caused by user interaction, such as a mouse click, or it
could be triggered by some other program logic.
The object that raises the event is called the event sender.
The object that captures the event and responds to it is called the event
receiver.
The event sender class doesn’t know which object or method will receive
(handle) the events it raises. What is needed is an intermediary (or pointerlike mechanism, delegate) between the source and the receiver.
An event is a member of a delegate type that enables an object or class to
provide notifications.
Delegate
Sender
9
COMPSCI280
Receiver
Example:

Declare a delegate that takes two parameters:


the source that raised the event, and
the data for the event
public delegate void EventHandler(object sender, System.EventArgs e);

In the Button class (e.g. in a Windows Forms Application)



Defines a click event of type EventHandler
Inside the Button class, the click member is exactly like a field of type
EventHandler
Outside the Button class, the click member can only be used on the lefthand side of the += and -= operators.

10
The += operator adds a handler for the event and -= removes a handler for the
event
public class Button {
public event EventHandler Click;
public void Reset() {
Click = null;
}
…
COMPSCI280
Example:

In the Form1 class (Windows application)



Create a button object
Create a event handler method
Connect the event handler method to the click event of the
button object
Event handler
method

A lot of this is set up for you when your create a
new Windows Forms Application in VS and drag a
button onto it.
public Form1() {
...
button1.Click += new EventHandler(button1_Click);
}
public void button1_Click(object sender, EventArgs e){
Console.WriteLine("Clicked");
}
You can also reuse the same method for multiple events
button2.Click += new EventHandler(button1_Click);
button3.Click += new EventHandler(button1_Click);
11
COMPSCI280
Lambda expressions

A lambda expression is


An anonymous function used to create delegates or expression tree* types
Denoted with =>



Can pronounce as ‘maps to’, ‘such that’ or ‘for which’
Same order of operations precedence as assignment with =
Lambda expressions let you write local functions that can be
passed as arguments or returned as the value of function calls


Borrowing liberally from http://msdn.microsoft.com/enus/library/bb397687.aspx
Particularly helpful for writing LINQ query expressions
You can assign a lambda expression to a delegate type
* See next slide
12
COMPSCI 280
Expression trees

Holding an expression in a dynamic structure



For C# this is as a nested series of objects
E.g. a binary operator like + can have Left and
Right terms, each of which themselves might
be variables, constants or other operators
A lambda expression is just ‘syntactic
sugar’


It’s an easier way to write stuff that the
(a+b)*c+7
compiler turns into delegate definitions
http://commons.wikimedia.org/wiki/File:Exptree-ex-11.svg
or expression trees
Great further explanation at https://www.youtube.com/watch?v=P60pt5xlms0
and https://www.youtube.com/watch?v=0YJECE45jhk

13
Author Jamie King almost sounds drunk, but I think that’s just his natural speaking style
COMPSCI 280
Syntactic sugar

So as Jamie King illustrates on YouTube
Func<int, bool> test= i => i > 5;

Is equivalent to
static bool qwerty(int i) { return i > 5; }
Func<int,bool> test=qwerty;

Either way, you can do

14
and then
Console.Writeline(test(3));
Console.Writeline(test(8));
False
True
COMPSCI 280
Handout 07
Definition

Expression lambda



In general looks like (x, y) => x==y
When there’s only one parameter you can skip the parentheses
Statement lambda

Statements in curly braces for the right-hand side of the lambda

The above example is a function of type void, but you could include
one or more return statements in the code, too

15
E.g. to perform a logical test for a bool delegate or compute a number for
an int delegate
COMPSCI 280
Use in queries

Very convenient in interaction with LINQ
Using an array as the
data source for the
query in this case

The type of the first input (e.g. the ‘n’ above) is inferred to be
the type of the elements in the source sequence

So if we are using a database connection we may have the result of
referencing a table or from a query, such as
IEnumerable<Customer> (iterator on a set of Customer instances)

And then we can do a query like:
customers.Where(c => c.City == "London");

16
Read “Customers,
c, such that c’s city
is London”
In this case the ‘c’ has access to the Customer object’s properties
(e.g. the City property, which might’ve been sourced from a field of
that name in a customer table under MySQL)
COMPSCI 280
Conclusion

The ability to have variables reference functions is powerful


Allows us to achieve a high degree of modularity between a ‘supervisor’
procedure and the procedures delegated to do subtasks
Provides a powerful framework for event handling


Lambda expressions are a convenient syntax for plugging anonymous
functions into your code



17
Useful for many things, including responding to user actions in a Graphical User
Interface (GUI)
Useful for many things including implementing query criteria
Keep (or get!) going with assignment 2
Next – we’ll look at further useful VS and C# features
COMPSCI 280
Download