Delegate.Combine() не работает - C#

Узнай цену своей работы

Формулировка задачи:

Читаю Троелсена "C# 5.0 и платформа .NET 4.5" и дошел до делегатов. В главе "Включение группового вызова" рассказывается, что использование метода Delegate.Combine() эквивалентно использованию операции +=. Однако в прилагающемся в книге примере Delegate.Combine() не работает так, как ожидается, т.е. не добавляет еще один вызов. Методом долгого научного тыка пришел к выводу, что применение операции += вместо Delegate.Combine() решает проблему. Но теперь мучает вопрос, почему один из способов не работает. На МСДНе по этому поводу ничего не нашел. Код примера прилагаю:
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace CarDelegate
  7. {
  8. class Program
  9. {
  10. static void Main( string[] args )
  11. {
  12. Console.WriteLine("***** Delegates as event enablers *****\n");
  13. // First, make a Car object.
  14. Car c1 = new Car("SlugBug", 100, 10);
  15. c1.RegisterWithCarEngine(new Car.CarEngineHandler(OnCarEngineEvent));
  16. // This time, hold onto the delegate object,
  17. // so we can unregister later.
  18. Car.CarEngineHandler handler2 = new Car.CarEngineHandler(OnCarEngineEvent2);
  19. c1.RegisterWithCarEngine(handler2);
  20. // Speed up (this will trigger the events).
  21. Console.WriteLine("***** Speeding up *****");
  22. for (int i = 0; i < 6; i++)
  23. c1.Accelerate(20);
  24. // Unregister from the second handler.
  25. c1.UnRegisterWithCarEngine(handler2);
  26. // We won't see the 'uppercase' message anymore!
  27. Console.WriteLine("***** Speeding up *****");
  28. for (int i = 0; i < 6; i++)
  29. c1.Accelerate(20);
  30. Console.ReadLine();
  31. }
  32. #region Delegate targets
  33. // We now have TWO methods that will be called by the Car
  34. // when sending notifications.
  35. public static void OnCarEngineEvent( string msg )
  36. {
  37. Console.WriteLine("\n***** Message From Car Object *****");
  38. Console.WriteLine("=> {0}", msg);
  39. Console.WriteLine("***********************************\n");
  40. }
  41. public static void OnCarEngineEvent2( string msg )
  42. {
  43. Console.WriteLine("=> {0}", msg.ToUpper());
  44. }
  45. #endregion
  46. }
  47. }
  48. using System;
  49. using System.Collections.Generic;
  50. using System.Linq;
  51. using System.Text;
  52. using System.Threading.Tasks;
  53. namespace CarDelegate
  54. {
  55. public class Car
  56. {
  57. // Internal state data.
  58. public int CurrentSpeed { get; set; }
  59. public int MaxSpeed { get; set; }
  60. public string PetName { get; set; }
  61. // Is the car alive or dead?
  62. private bool carIsDead;
  63. // Class constructors.
  64. public Car() { MaxSpeed = 100; }
  65. public Car( string name, int maxSp, int currSp )
  66. {
  67. CurrentSpeed = currSp;
  68. MaxSpeed = maxSp;
  69. PetName = name;
  70. }
  71. #region Delegate infrastructure
  72. // 1) Define a delegate type.
  73. public delegate void CarEngineHandler( string msgForCaller );
  74. // 2) Define a member variable of this delegate.
  75. private CarEngineHandler listOfHandlers;
  76. // 3) Add registration function for the caller.
  77. public void RegisterWithCarEngine( CarEngineHandler methodToCall )
  78. {
  79. // listOfHandlers = methodToCall;
  80. // listOfHandlers += methodToCall;
  81. // listOfHandlers += methodToCall;
  82. if (listOfHandlers == null)
  83. listOfHandlers = methodToCall;
  84. else
  85. //listOfHandlers += methodToCall;
  86. //Если раскомментировать верхнюю строку и закомментировать нижнюю, то OnCarEngineEvent2 будет вызваться
  87. Delegate.Combine(listOfHandlers, methodToCall);
  88. }
  89. public void UnRegisterWithCarEngine( CarEngineHandler methodToCall )
  90. {
  91. listOfHandlers -= methodToCall;
  92. }
  93. // 4) Implement the Accelerate() method to invoke the delegate’s
  94. // invocation list under the correct circumstances.
  95. public void Accelerate( int delta )
  96. {
  97. // If this car is 'dead', send dead message.
  98. if (carIsDead)
  99. {
  100. if (listOfHandlers != null)
  101. listOfHandlers("Sorry, this car is dead...");
  102. }
  103. else
  104. {
  105. CurrentSpeed += delta;
  106. // Is this car 'almost dead'?
  107. if (10 == (MaxSpeed - CurrentSpeed)
  108. && listOfHandlers != null)
  109. {
  110. listOfHandlers("Careful buddy! Gonna blow!");
  111. }
  112. if (CurrentSpeed >= MaxSpeed)
  113. carIsDead = true;
  114. else
  115. Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
  116. }
  117. }
  118. #endregion
  119. }
  120. }

Решение задачи: «Delegate.Combine() не работает»

textual
Листинг программы
  1. Delegate.Combine(listOfHandlers, methodToCall);

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.2 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут