Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

C# ПІДРУЧНИКИ / c# / MS Press - Msdn Training Programming Net Framework With C#

.pdf
Скачиваний:
193
Добавлен:
12.02.2016
Размер:
16.87 Mб
Скачать

Module 8: Delegates and Events

11

 

 

 

This code generates the following output:

Before flipping, the switch is: Down Flipping switch ...

... bathroom light is on

After flipping, the switch is: Up

Before flipping, the switch is: Up Flipping switch ...

... bathroom light is off

After flipping, the switch is: Down

Before flipping, the switch is: Down Flipping switch ...

... bedroom light is on

After flipping, the switch is: Up

Before flipping, the switch is: Up Flipping switch ...

... bedroom light is off

After flipping, the switch is: Down

12

Module 8: Delegates and Events

" Multicast Delegates

Topic Objective

To provide an overview of the topics in this section.

Lead-in

If you change the state in one object, you may need to broadcast that change to multiple objects.

!Multicast Delegate Scenario

!Single vs. Multicast Delegates

!Creating and Invoking Multicast Delegates

!C# Language-Specific Syntax

!Delegate Details

*****************************ILLEGAL FOR NON-TRAINER USE******************************

For Your Information

As noted in the C# Language-Specific Syntax in this module, delegate types with a void return value in C# cause the compiler to derive the delegate class from the MulticastDelegate class.

If you change the state in one object, you may need to broadcast that change to multiple objects. You can use multicast delegate objects to provide this functionality; they can be composed together so that a single invocation invokes all of their methods, just as a single light switch can turn on or off all lights connected to that switch.

Module 8: Delegates and Events

13

 

 

 

Multicast Delegate Scenario

Topic Objective

To illustrate the typical multicast delegate use by using the common scenario of a switch that controls two light bulbs.

Lead-in

The following scenario of a switch that controls two lights illustrates the use of multicast delegates.

 

 

4 - OnFlipCallback method

1 - Change in

Switch Object

changes light1’s state

switch position

 

invokes switch’s

 

Light1 Object

OnFlip method

 

 

Light2 Object

 

OnFlip method

OnFlipCallback

 

 

 

method

OnFlipCallback

2 - OnFlip method

 

 

3 - delegate1 invokes

method

invokes multicast

 

delegate1

light1’s OnFlipCallback

7 - OnFlipCallback

 

 

 

 

Invocation list

 

method changes

 

 

light2’s state

 

Multicast delegate1 object

 

 

 

 

 

Multicast delegate1 object

 

 

5 - delegate2

Multicast delegate2 object

6 - delegate2 invokes

is invoked

Multicast delegate2 object

light2’s OnFlipCallback

 

*****************************ILLEGAL FOR NON-TRAINER USE******************************

To run the build slide, click through the lower-left button on the slide.

The following scenario of a switch that controls two lights illustrates the use of multicast delegates. The switch object models the light switch, and the two light objects model the two electric lights. To provide the capability to dynamically connect, disconnect, and reconnect light object methods to the switch object, the switch object is dynamically connected to the light objects by instantiating and composing two multicast delegate objects.

In the light scenario, multicast delegate1 refers to the light1 object’s

OnFlipCallback method, and multicast delegate2 refers to the light2 object’s

OnFlipCallback method. Their composition logically represents an invocation list, a list of methods that are executed when the delegate is invoked. In this case, the invocation list consists of these two methods.

In the light switch scenario shown in the slide, the multicast delegate objects encapsulate references to two objects and two methods. When the switch is flipped:

1.The switch object’s OnFlip method is invoked.

2.The OnFlip method invokes the multicast delegate1 object.

3.The multicast delegate1 object first invokes the light1 object’s

OnFlipCallback method.

4.The light1 object’s OnFlipCallback method changes the state of the light1 object.

5.The multicast delegate1 object next invokes the multicast delegate2 object.

6.The multicast delegate2 object invokes the light2 object’s

OnFlipCallback method.

7.The light2 object’s OnFlipCallback method changes the state of the light2 object.

You can compose additional multicast delegates to allow the switch to control additional lights.

14

Module 8: Delegates and Events

Single vs. Multicast Delegates

Topic Objective

To explain the difference between single-cast and multicast delegates.

Lead-in

When delegate declarations are compiled, the compiler generates a new class, which derives from two delegate classes provided by the .NET Framework.

!All Delegates Have an Invocation List of Methods That Are Executed When Their Invoke Method is Called

!Single-Cast Delegates: Derived Directly From System.MulticastDelegate

#Invocation list contains only one method

!Multicast Delegates: Derived from System.MulticastDelegate

#Invocation list may contain multiple methods

#Multicast delegates contain two static methods to add and remove references from invocation list: Combine and Remove

!Use GetInvocationList to Obtain an Invocation List as an Array of Delegate References

!Use a Delegate’s Target and Method Properties to Determine:

#Which object will receive the callback

#Which method will be called

*****************************ILLEGAL FOR NON-TRAINER USE******************************

When delegate declarations are compiled, the compiler, in effect, generates a new class. The new delegate class derives from the System.MulticastDelegate class that is provided by the .NET Framework.

All delegates have an invocation list, or linked list of delegates that are executed when the invoke method is called. A delegate that derives from the MulticastDelegate class may contain an invocation list with multiple delegates.

The MulticastDelegate class contains two static methods to add and remove method references from an invocation list: Combine and Remove.

Combine is declared as follows:

public static Delegate Combine( Delegate a,

Delegate b);

The method returns a new multicast Delegate object with an invocation list that concatenates the invocation lists of a and b in that order.

Remove is declared as follows:

public static Delegate Remove( Delegate source,

Delegate value);

The method returns a new Delegate object with an invocation list formed by taking the invocation list of source and removing the last occurrence of value, if value is found in the invocation list of source. If value is null or if value is not found, then source is returned.

You can use the method GetInvocationList to obtain the invocation list as an array of delegate references. You can also use the delegate’s Target and Method properties to determine which object is to receive the callback and which method is to be called. In the case of a static method, Target is null.

Module 8: Delegates and Events

15

 

 

 

Creating and Invoking Multicast Delegates

Topic Objective

To provide specific examples of how to create and invoke multicast delegates, and how to iterate though an invocation list to invoke specific delegates.

Lead-in

This sample code shows how to create and invoke multicast delegates, and how to iterate through an invocation list to invoke specific delegates.

// assign to c the composition of delegates a and b // assign to c the composition of delegates a and b c = (MyDelegate2)Delegate.Combine(a, b);

c = (MyDelegate2)Delegate.Combine(a, b);

// assign to d the result of removing a from c // assign to d the result of removing a from c d = (MyDelegate2)Delegate.Remove(c, a);

d = (MyDelegate2)Delegate.Remove(c, a);

// Iterate through c's invocation list // Iterate through c's invocation list // and invoke all delegates except a // and invoke all delegates except a

Delegate[] DelegateList = c.GetInvocationList(); Delegate[] DelegateList = c.GetInvocationList(); for (int i = 0; i < DelegateList.Length; i++) { for (int i = 0; i < DelegateList.Length; i++) { if (DelegateList[i].Target != aFoo1) {

if (DelegateList[i].Target != aFoo1) { ((MyDelegate2) DelegateList[i])(); ((MyDelegate2) DelegateList[i])();

}}

}}

*****************************ILLEGAL FOR NON-TRAINER USE******************************

The following sample code shows:

!How to create multicast delegate objects.

!How to write code to invoke delegates’ Combine and Remove methods.

!How to write code to iterate through an invocation list invoking all delegates, except those delegates whose target is a specific object.

16

Module 8: Delegates and Events

using System;

public delegate void MyDelegate2();

public class Foo

{

public void Bar() { Console.WriteLine("Bar invoked");

}

}

class Application {

public static void Main() { Foo aFoo1 = new Foo(); Foo aFoo2 = new Foo();

MyDelegate2 a, b, c, d;

a = new MyDelegate2(aFoo1.Bar); b = new MyDelegate2(aFoo2.Bar);

//assign to delegate c the composition of delegates a and b c = (MyDelegate2)Delegate.Combine(a , b);

//assign to d the result of removing a from c

d = (MyDelegate2)Delegate.Remove(c , a);

//iterate through c's invocation list

//and invoke all delegates except those that target aFoo1 Delegate[] DelegateList = c.GetInvocationList();

for (int i = 0; i < DelegateList.Length; i++) {

if (DelegateList[i].Target != aFoo1) { ((MyDelegate2) DelegateList[i])();

}

}

}

}

The preceding code invokes the delegate that invokes object aFoo2’s Bar method and outputs:

Bar invoked

Module 8: Delegates and Events

17

 

 

 

C# Language-Specific Syntax

Topic Objective

To present helpful alternative C# syntax.

Lead-in

Delegate types with a void return value in C# cause the compiler to derive the delegate class from the

MulticastDelegate class.

!C# Delegates That Return Void Are Multicast Delegates

!In C#, Use the + and - Operators to Add and Remove Invocation List Entries

#Less verbose than Combine and Remove methods

 

MyDelegate a, b, c, d;

 

 

 

 

MyDelegate a, b, c, d;

 

 

a = new

MyDelegate(Foo);

 

 

a = new

MyDelegate(Foo);

 

 

b = new

MyDelegate(Bar);

 

 

b = new

MyDelegate(Bar);

 

 

c = a +

b;

// Compose two delegates to make another

 

 

c = a +

b;

// Compose two delegates to make another

 

 

d = c -

a;

// Remove a from the composed delegate

 

 

d = c -

a;

// Remove a from the composed delegate

 

 

a += b;

 

// Add delegate b to a's invocation list

 

 

a += b;

 

// Add delegate b to a's invocation list

 

 

a -= b;

 

// Remove delegate b from a's list

 

 

a -= b;

 

// Remove delegate b from a's list

 

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Delegate types with a void return value in C# cause the compiler to derive the delegate class from the MulticastDelegate class. You can also use these delegates’ addition operator (+) and the subtraction operator (-) to invoke the Combine and Remove methods for delegate composition and decomposition.

18

Module 8: Delegates and Events

Demonstration: Multicast Delegates

Topic Objective

To demonstrate how to use the + and operators to add and remove methods.

Lead-in

You can add and remove methods from the invocation list of multicast delegates by using the + and operators.

*****************************ILLEGAL FOR NON-TRAINER USE******************************

Delivery Tip

Use Visual Studio .NET to run this code. Set breakpoints or single-step to illustrate the sequence of events.

In this demonstration, you will learn how to add and remove methods from the invocation list of multicast delegates by using the + and operators.

using System;

namespace Multicast_Delegates

{

delegate void MyDelegate3(string s);

class MyClass

{

public static void Hello(string s) { Console.WriteLine(" Hello, {0}!", s);

}

public static void Goodbye(string s) { Console.WriteLine(" Goodbye, {0}!", s);

}

(Code continued on the following page.)

 

Module 8: Delegates and Events

19

public static void Main() {

 

 

MyDelegate3 a, b, c, d;

 

 

a = new MyDelegate3(MyClass.Hello);

 

 

b = new MyDelegate3(MyClass.Goodbye);

 

 

c = a + b;

// Compose two delegates to make another

 

 

d = c - a;

// Remove a from c to make another

 

 

Console.WriteLine("Invoking delegate a:"); a("A");

Console.WriteLine("Invoking delegate b:"); b("B");

Console.WriteLine("Invoking delegate c:"); c("C");

Console.WriteLine("Invoking delegate d:"); d("D");

Console.WriteLine("Adding b to a and invoking:");

a += b;

// Add the b delegate to a

a("E");

 

Console.WriteLine("Removing b from a and invoking:");

a -= b;

// Remove the b delegate from a

a("F");

 

}

}

}

This code generates the following output:

Invoking delegate a:

Hello, A!

Invoking delegate b:

Goodbye, B!

Invoking delegate c:

Hello, C!

Goodbye, C!

Invoking delegate d:

Goodbye, D!

Adding b to a and invoking:

Hello, E!

Goodbye, E!

Removing b from a and invoking:

Hello, F!

};
};

20

Module 8: Delegates and Events

Delegate Details

Topic Objective

To show how a delegate declaration is handled by the compiler.

Lead-in

When delegate declarations are compiled, the compiler generates a new class that derives from

System.Delegate.

!A Delegate Declaration Causes the Compiler to Generate a New Class

//delegate void MyDelegate3(string val);

//delegate void MyDelegate3(string val);

class MyDelegate3 : System.MulticastDelegate {

class MyDelegate3 : System.MulticastDelegate {

public MyDelegate3(object obj, methodref mref)

public MyDelegate3(object obj, methodref mref)

: base (obj, mref) { //...

: base (obj, mref) { //...

}}

public void virtual Invoke(string val) { //...

public void virtual Invoke(string val) { //...

}}

*****************************ILLEGAL FOR NON-TRAINER USE******************************

For Your Information

There is no actual type named methodref, but having an instance of a type that encapsulates a reference to a class method resembles what the compiler actually does.

As previously noted in this module, when delegate declarations are compiled, the compiler, in effect, generates a new class that derives from System.Delegate. The new delegate class has two members: a constructor and an Invoke method. The following class declaration resembles what the compiler actually does:

// delegate void MyDelegate3(string val);

class MyDelegate3 : System.MulticastDelegate { public MyDelegate3(object obj, methodref mref)

: base (obj, mref) {//...

}

public void virtual Invoke(string val) {//...

}

}

The first member is a constructor: its first parameter is the delegate’s target object, and its second parameter is a reference to a method. When a delegate refers to a static method, the target object is null.

The Invoke method for the class MyDelegate3 indicates that delegate instances of this class encapsulate methods that have a void return and a single string parameter. When a delegate is invoked, the Invoke method is called with the specified parameters.

Соседние файлы в папке c#