Delegate.Combine() не работает - C#
Формулировка задачи:
Читаю Троелсена "C# 5.0 и платформа .NET 4.5" и дошел до делегатов. В главе "Включение группового вызова" рассказывается, что использование метода Delegate.Combine() эквивалентно использованию операции +=. Однако в прилагающемся в книге примере Delegate.Combine() не работает так, как ожидается, т.е. не добавляет еще один вызов. Методом долгого научного тыка пришел к выводу, что применение операции += вместо Delegate.Combine() решает проблему. Но теперь мучает вопрос, почему один из способов не работает. На МСДНе по этому поводу ничего не нашел.
Код примера прилагаю:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarDelegate
{
class Program
{
static void Main( string[] args )
{
Console.WriteLine("***** Delegates as event enablers *****\n");
// First, make a Car object.
Car c1 = new Car("SlugBug", 100, 10);
c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
// This time, hold onto the delegate object,
// so we can unregister later.
Car.CarEngineHandler handler2 = new Car.CarEngineHandler(OnCarEngineEvent2);
c1.RegisterWithCarEngine(handler2);
// Speed up (this will trigger the events).
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
// Unregister from the second handler.
c1.UnRegisterWithCarEngine(handler2);
// We won't see the 'uppercase' message anymore!
Console.WriteLine("***** Speeding up *****");
for (int i = 0; i < 6; i++)
c1.Accelerate(20);
Console.ReadLine();
}
#region Delegate targets
// We now have TWO methods that will be called by the Car
// when sending notifications.
public static void OnCarEngineEvent( string msg )
{
Console.WriteLine("\n***** Message From Car Object *****");
Console.WriteLine("=> {0}", msg);
Console.WriteLine("***********************************\n");
}
public static void OnCarEngineEvent2( string msg )
{
Console.WriteLine("=> {0}", msg.ToUpper());
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CarDelegate
{
public class Car
{
// Internal state data.
public int CurrentSpeed { get; set; }
public int MaxSpeed { get; set; }
public string PetName { get; set; }
// Is the car alive or dead?
private bool carIsDead;
// Class constructors.
public Car() { MaxSpeed = 100; }
public Car( string name, int maxSp, int currSp )
{
CurrentSpeed = currSp;
MaxSpeed = maxSp;
PetName = name;
}
#region Delegate infrastructure
// 1) Define a delegate type.
public delegate void CarEngineHandler( string msgForCaller );
// 2) Define a member variable of this delegate.
private CarEngineHandler listOfHandlers;
// 3) Add registration function for the caller.
public void RegisterWithCarEngine( CarEngineHandler methodToCall )
{
// listOfHandlers = methodToCall;
// listOfHandlers += methodToCall;
// listOfHandlers += methodToCall;
if (listOfHandlers == null)
listOfHandlers = methodToCall;
else
//listOfHandlers += methodToCall;
//Если раскомментировать верхнюю строку и закомментировать нижнюю, то OnCarEngineEvent2 будет вызваться
Delegate.Combine(listOfHandlers, methodToCall);
}
public void UnRegisterWithCarEngine( CarEngineHandler methodToCall )
{
listOfHandlers -= methodToCall;
}
// 4) Implement the Accelerate() method to invoke the delegate’s
// invocation list under the correct circumstances.
public void Accelerate( int delta )
{
// If this car is 'dead', send dead message.
if (carIsDead)
{
if (listOfHandlers != null)
listOfHandlers("Sorry, this car is dead...");
}
else
{
CurrentSpeed += delta;
// Is this car 'almost dead'?
if (10 == (MaxSpeed - CurrentSpeed)
&& listOfHandlers != null)
{
listOfHandlers("Careful buddy! Gonna blow!");
}
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
#endregion
}
}Решение задачи: «Delegate.Combine() не работает»
textual
Листинг программы
Delegate.Combine(listOfHandlers, methodToCall);