Delegates and Events Tom Roeder CS 215 2006

  • Slides: 23
Download presentation
Delegates and Events Tom Roeder CS 215 2006 fa

Delegates and Events Tom Roeder CS 215 2006 fa

Motivation – Function Pointers l Treat functions as first-class objects l eg. Scheme: (map

Motivation – Function Pointers l Treat functions as first-class objects l eg. Scheme: (map myfunc somelist) l l l works because functions are lists eg. Mathematica: {#, #^2} & /@ Range[1, 10] eg. C/C++: typedef int (*fptr)(int*); int my_method(int* var) { if (var != NULL) return *var; } fptr some_method = my_method; int take_f_param(fptr g) { int x = 10; int y = &x; return g(y); } printf(“%dn”, take_f_param(some_method)); l Works because functions are pointers to code

Motivation – Function Pointers l Java l l no equivalent way to get function

Motivation – Function Pointers l Java l l no equivalent way to get function pointers use inner classes that contain methods or simply use interfaces Why not? l l functions are not objects same problem as integers

Comparators l Sort method on many containers l l l provides efficient sorting needs

Comparators l Sort method on many containers l l l provides efficient sorting needs to be able to compare to objects Solution: IComparer public class Arrival. Comparer: IComparer { public Arrival. Comparer() {} public int Compare(object x, object y) { return ((Process)x). Arrival. Compare. To(((Process)y). Arrival); } } l Can then call l sorted. List. Sort(new Arrival. Comparer());

Delegates l An objectified function l l inherits from System. Delegate sealed implicitly looks

Delegates l An objectified function l l inherits from System. Delegate sealed implicitly looks much like C/C++ style function pointer eg. delegate int Func(ref int x) l l l defines a new type: Func: takes int, returns int declared like a function with an extra keyword stores a list of methods to call

Delegates – Example delegate int Func(ref int x); int Increment(ref int x) { return

Delegates – Example delegate int Func(ref int x); int Increment(ref int x) { return x++; } int Decrement(ref int x) { return x--; } Func F 1 = new Func(Increment); F 1 += Decrement; x = 10; Console. Write. Line(F 1(ref x)); Console. Write. Line(x); l Delegate calls methods in order l l ref values updated between calls return value is the value of the last call

Delegates – Usage Patterns l l Declared like a function Instantiated like a reference

Delegates – Usage Patterns l l Declared like a function Instantiated like a reference type l l Modified with +, -, +=, -= l l l takes a method parameter in the constructor can add more than one instance of a method - removes the last instance of the method in the list Called like a function: functional programming

Delegates – Usage Examples delegate int Func(int x); List<int> Map(Func d, List<int> l) {

Delegates – Usage Examples delegate int Func(int x); List<int> Map(Func d, List<int> l) { List<int> new. L = new List<int>(); foreach(int i in l) { new. L. Add(d(l)); } return new. L; } l Allows code written in a more functional style

Notes on Delegates l this pointer captured by instance delegates l l thus can

Notes on Delegates l this pointer captured by instance delegates l l thus can capture temporary objects from method calls or elsewhere in delegates eg. delegate int Func(int x); Func f = new Func(); … { Temp. Object o = new Temp. Object(); f += o. m; } // o is now out of scope

Covariance & Contravariance l If the type of the return value is subclass l

Covariance & Contravariance l If the type of the return value is subclass l l l then the delegate is still acceptable called covariance If the type of the args are subclasses l l then the delegate is likewise acceptable called contravariance

Anonymous Methods Func f = new Func(); int y = 10; f += delegate(int

Anonymous Methods Func f = new Func(); int y = 10; f += delegate(int x) { return x + y; } l Creates a method and adds it to delegate l l l treated the same as other methods good for one-time, short delegates Variables captured by anonymous method l l outer variables like y in the above example

Anonymous Methods l l using System; delegate void D(); class Test { static D[]

Anonymous Methods l l 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] = delegate { Console. Write. Line(x); }; } return result; } static void Main() { foreach (D d in F()) d(); } }

Anonymous Methods l l static D[] F() { D[] result = new D[3]; int

Anonymous Methods l l static D[] F() { D[] result = new D[3]; int x; for (int i = 0; i < 3; i++) { x = i * 2 + 1; result[i] = delegate { Console. Write. Line(x); }; } return result; } First returns 1, 3, 5. Second returns 5, 5, 5 l l l Outer variables are captured locations Not given values at delegate creation time Can communicate through outer variables

Events l Special class of delegates l l given the event keyword class Room

Events l Special class of delegates l l given the event keyword class Room { public event Event. Handler Enter; public void Register. Guest(object source, Event. Args e) { … } public static void Main(string[] args) { Enter += new Event. Handler(Register. Guest); if (Enter != null) { Enter(this, new Event. Args()); } } }

Events l Enter is an object of type delegate l l l when event

Events l Enter is an object of type delegate l l l when event is “raised” each delegate called C# allows any delegate to be attached to an event. NET requires only Event. Handlers l l needed for CLS compatibility Adds restrictions to the delegate l l can only raise an event in its defining class outside, can only do += and -= : return void

Events l Modifiers on events l l Delegates cannot be defined in interfaces l

Events l Modifiers on events l l Delegates cannot be defined in interfaces l l public/private: define accessibility of += and -= events can be defined in interfaces Since can only do += and -= outside, how do we raise events? l l normally with methods: eg. Button. On. Click sole purpose is to raise the event

Events – Accessors l add and remove accessors l l can be explicitly defined

Events – Accessors l add and remove accessors l l can be explicitly defined for events use anonymous methods normally generated by compiler For example l l l when want to control the space used for storage access the custom data structure in On. Click() or use to control accessibility

Events - Uses l Registering callbacks l l common programming paradigm examples in OS

Events - Uses l Registering callbacks l l common programming paradigm examples in OS and threaded code any asynchronous code does this Windowing code l l l eg. Button. On. Click basis of Windows. Forms Handles the asynchrony of the user

Event-Based Programming l Style of concurrent programming l l l contrasts with thread based

Event-Based Programming l Style of concurrent programming l l l contrasts with thread based concurrency based on the number of events not on the number of processors l l although limited by number of processors events in C# could be backed by an eventbased system l full support for events already in language

Generics and Delegates l Delegates can use generic parameters: delegate int Func<T>(T t) l

Generics and Delegates l Delegates can use generic parameters: delegate int Func<T>(T t) l allows interaction with generic classes class Test<T> { public Test(Func<T> f, T val) { … } l l l Is the type Func<T> open or closed? Methods can use delegates similarly Both can add where constraints like classes

Generics and Delegates l Does the following work? delegate int F<T>(int x); class Test

Generics and Delegates l Does the following work? delegate int F<T>(int x); class Test 2<T, U> where T : class where U : F<T> { … } l l no: type constraints cannot be sealed classes can, however, change F<T> to System. Delegate l then we lose some ability to statically typecheck

Homework 2 - Polynomials l Build a class that implements the polynomials l l

Homework 2 - Polynomials l Build a class that implements the polynomials l l polynomials in some abstract variables and further must be generic in their scalars l l only constraint: must have – and + is this possible? § l add methods to add, subtract, and multiply l l What should be our solution? return Polynomials of same type add an indexer to get i-th term

Homework 3 – Sets l Write a Set<T> l l implements the union, intersection,

Homework 3 – Sets l Write a Set<T> l l implements the union, intersection, and difference implements IEnumerable<T> implements a Filter methods Questions?