Notification.cs 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2. using System.Diagnostics;
  3. using System.Globalization;
  4. using System.Collections.Generic;
  5. using System.Reactive.Concurrency;
  6. #pragma warning disable 0659
  7. #pragma warning disable 0661
  8. namespace System.Reactive
  9. {
  10. /// <summary>
  11. /// Indicates the type of a notification.
  12. /// </summary>
  13. public enum NotificationKind
  14. {
  15. /// <summary>
  16. /// Represents an OnNext notification.
  17. /// </summary>
  18. OnNext,
  19. /// <summary>
  20. /// Represents an OnError notification.
  21. /// </summary>
  22. OnError,
  23. /// <summary>
  24. /// Represents an OnCompleted notification.
  25. /// </summary>
  26. OnCompleted
  27. }
  28. /// <summary>
  29. /// Represents a notification to an observer.
  30. /// </summary>
  31. /// <typeparam name="T">The type of the elements received by the observer.</typeparam>
  32. #if !NO_SERIALIZABLE
  33. [Serializable]
  34. #endif
  35. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals", Justification = "Resembles a discriminated union with finite number of subclasses (external users shouldn't create their own subtypes), each of which does override GetHashCode itself.")]
  36. public abstract class Notification<T> : IEquatable<Notification<T>>
  37. {
  38. /// <summary>
  39. /// Default constructor used by derived types.
  40. /// </summary>
  41. protected internal Notification()
  42. {
  43. }
  44. /// <summary>
  45. /// Returns the value of an OnNext notification or throws an exception.
  46. /// </summary>
  47. public abstract T Value
  48. {
  49. get;
  50. }
  51. /// <summary>
  52. /// Returns a value that indicates whether the notification has a value.
  53. /// </summary>
  54. public abstract bool HasValue
  55. {
  56. get;
  57. }
  58. /// <summary>
  59. /// Returns the exception of an OnError notification or returns null.
  60. /// </summary>
  61. public abstract Exception Exception
  62. {
  63. get;
  64. }
  65. /// <summary>
  66. /// Gets the kind of notification that is represented.
  67. /// </summary>
  68. public abstract NotificationKind Kind
  69. {
  70. get;
  71. }
  72. /// <summary>
  73. /// Represents an OnNext notification to an observer.
  74. /// </summary>
  75. #if !NO_DEBUGGER_ATTRIBUTES
  76. [DebuggerDisplay("OnNext({Value})")]
  77. #endif
  78. #if !NO_SERIALIZABLE
  79. [Serializable]
  80. #endif
  81. internal sealed class OnNextNotification : Notification<T>
  82. {
  83. T value;
  84. /// <summary>
  85. /// Constructs a notification of a new value.
  86. /// </summary>
  87. public OnNextNotification(T value)
  88. {
  89. this.value = value;
  90. }
  91. /// <summary>
  92. /// Returns the value of an OnNext notification.
  93. /// </summary>
  94. public override T Value { get { return value; } }
  95. /// <summary>
  96. /// Returns null.
  97. /// </summary>
  98. public override Exception Exception { get { return null; } }
  99. /// <summary>
  100. /// Returns true.
  101. /// </summary>
  102. public override bool HasValue { get { return true; } }
  103. /// <summary>
  104. /// Returns NotificationKind.OnNext.
  105. /// </summary>
  106. public override NotificationKind Kind { get { return NotificationKind.OnNext; } }
  107. /// <summary>
  108. /// Returns the hash code for this instance.
  109. /// </summary>
  110. public override int GetHashCode()
  111. {
  112. return EqualityComparer<T>.Default.GetHashCode(Value);
  113. }
  114. /// <summary>
  115. /// Indicates whether this instance and a specified object are equal.
  116. /// </summary>
  117. public override bool Equals(Notification<T> other)
  118. {
  119. if (Object.ReferenceEquals(this, other))
  120. return true;
  121. if (Object.ReferenceEquals(other, null))
  122. return false;
  123. if (other.Kind != NotificationKind.OnNext)
  124. return false;
  125. return EqualityComparer<T>.Default.Equals(Value, other.Value);
  126. }
  127. /// <summary>
  128. /// Returns a string representation of this instance.
  129. /// </summary>
  130. public override string ToString()
  131. {
  132. return String.Format(CultureInfo.CurrentCulture, "OnNext({0})", Value);
  133. }
  134. /// <summary>
  135. /// Invokes the observer's method corresponding to the notification.
  136. /// </summary>
  137. /// <param name="observer">Observer to invoke the notification on.</param>
  138. public override void Accept(IObserver<T> observer)
  139. {
  140. if (observer == null)
  141. throw new ArgumentNullException("observer");
  142. observer.OnNext(Value);
  143. }
  144. /// <summary>
  145. /// Invokes the observer's method corresponding to the notification and returns the produced result.
  146. /// </summary>
  147. /// <param name="observer">Observer to invoke the notification on.</param>
  148. /// <returns>Result produced by the observation.</returns>
  149. public override TResult Accept<TResult>(IObserver<T, TResult> observer)
  150. {
  151. if (observer == null)
  152. throw new ArgumentNullException("observer");
  153. return observer.OnNext(Value);
  154. }
  155. /// <summary>
  156. /// Invokes the delegate corresponding to the notification.
  157. /// </summary>
  158. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  159. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  160. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  161. public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
  162. {
  163. if (onNext == null)
  164. throw new ArgumentNullException("onNext");
  165. if (onError == null)
  166. throw new ArgumentNullException("onError");
  167. if (onCompleted == null)
  168. throw new ArgumentNullException("onCompleted");
  169. onNext(Value);
  170. }
  171. /// <summary>
  172. /// Invokes the delegate corresponding to the notification and returns the produced result.
  173. /// </summary>
  174. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  175. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  176. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  177. /// <returns>Result produced by the observation.</returns>
  178. public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
  179. {
  180. if (onNext == null)
  181. throw new ArgumentNullException("onNext");
  182. if (onError == null)
  183. throw new ArgumentNullException("onError");
  184. if (onCompleted == null)
  185. throw new ArgumentNullException("onCompleted");
  186. return onNext(Value);
  187. }
  188. }
  189. /// <summary>
  190. /// Represents an OnError notification to an observer.
  191. /// </summary>
  192. #if !NO_DEBUGGER_ATTRIBUTES
  193. [DebuggerDisplay("OnError({Exception})")]
  194. #endif
  195. #if !NO_SERIALIZABLE
  196. [Serializable]
  197. #endif
  198. internal sealed class OnErrorNotification : Notification<T>
  199. {
  200. Exception exception;
  201. /// <summary>
  202. /// Constructs a notification of an exception.
  203. /// </summary>
  204. public OnErrorNotification(Exception exception)
  205. {
  206. this.exception = exception;
  207. }
  208. /// <summary>
  209. /// Throws the exception.
  210. /// </summary>
  211. public override T Value { get { exception.Throw(); return default(T); } }
  212. /// <summary>
  213. /// Returns the exception.
  214. /// </summary>
  215. public override Exception Exception { get { return exception; } }
  216. /// <summary>
  217. /// Returns false.
  218. /// </summary>
  219. public override bool HasValue { get { return false; } }
  220. /// <summary>
  221. /// Returns NotificationKind.OnError.
  222. /// </summary>
  223. public override NotificationKind Kind { get { return NotificationKind.OnError; } }
  224. /// <summary>
  225. /// Returns the hash code for this instance.
  226. /// </summary>
  227. public override int GetHashCode()
  228. {
  229. return Exception.GetHashCode();
  230. }
  231. /// <summary>
  232. /// Indicates whether this instance and other are equal.
  233. /// </summary>
  234. public override bool Equals(Notification<T> other)
  235. {
  236. if (Object.ReferenceEquals(this, other))
  237. return true;
  238. if (Object.ReferenceEquals(other, null))
  239. return false;
  240. if (other.Kind != NotificationKind.OnError)
  241. return false;
  242. return Object.Equals(Exception, other.Exception);
  243. }
  244. /// <summary>
  245. /// Returns a string representation of this instance.
  246. /// </summary>
  247. public override string ToString()
  248. {
  249. return String.Format(CultureInfo.CurrentCulture, "OnError({0})", Exception.GetType().FullName);
  250. }
  251. /// <summary>
  252. /// Invokes the observer's method corresponding to the notification.
  253. /// </summary>
  254. /// <param name="observer">Observer to invoke the notification on.</param>
  255. public override void Accept(IObserver<T> observer)
  256. {
  257. if (observer == null)
  258. throw new ArgumentNullException("observer");
  259. observer.OnError(Exception);
  260. }
  261. /// <summary>
  262. /// Invokes the observer's method corresponding to the notification and returns the produced result.
  263. /// </summary>
  264. /// <param name="observer">Observer to invoke the notification on.</param>
  265. /// <returns>Result produced by the observation.</returns>
  266. public override TResult Accept<TResult>(IObserver<T, TResult> observer)
  267. {
  268. if (observer == null)
  269. throw new ArgumentNullException("observer");
  270. return observer.OnError(Exception);
  271. }
  272. /// <summary>
  273. /// Invokes the delegate corresponding to the notification.
  274. /// </summary>
  275. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  276. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  277. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  278. public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
  279. {
  280. if (onNext == null)
  281. throw new ArgumentNullException("onNext");
  282. if (onError == null)
  283. throw new ArgumentNullException("onError");
  284. if (onCompleted == null)
  285. throw new ArgumentNullException("onCompleted");
  286. onError(Exception);
  287. }
  288. /// <summary>
  289. /// Invokes the delegate corresponding to the notification and returns the produced result.
  290. /// </summary>
  291. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  292. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  293. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  294. /// <returns>Result produced by the observation.</returns>
  295. public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
  296. {
  297. if (onNext == null)
  298. throw new ArgumentNullException("onNext");
  299. if (onError == null)
  300. throw new ArgumentNullException("onError");
  301. if (onCompleted == null)
  302. throw new ArgumentNullException("onCompleted");
  303. return onError(Exception);
  304. }
  305. }
  306. /// <summary>
  307. /// Represents an OnCompleted notification to an observer.
  308. /// </summary>
  309. #if !NO_DEBUGGER_ATTRIBUTES
  310. [DebuggerDisplay("OnCompleted()")]
  311. #endif
  312. #if !NO_SERIALIZABLE
  313. [Serializable]
  314. #endif
  315. internal sealed class OnCompletedNotification : Notification<T>
  316. {
  317. /// <summary>
  318. /// Constructs a notification of the end of a sequence.
  319. /// </summary>
  320. public OnCompletedNotification()
  321. {
  322. }
  323. /// <summary>
  324. /// Throws an InvalidOperationException.
  325. /// </summary>
  326. public override T Value { get { throw new InvalidOperationException(Strings_Core.COMPLETED_NO_VALUE); } }
  327. /// <summary>
  328. /// Returns null.
  329. /// </summary>
  330. public override Exception Exception { get { return null; } }
  331. /// <summary>
  332. /// Returns false.
  333. /// </summary>
  334. public override bool HasValue { get { return false; } }
  335. /// <summary>
  336. /// Returns NotificationKind.OnCompleted.
  337. /// </summary>
  338. public override NotificationKind Kind { get { return NotificationKind.OnCompleted; } }
  339. /// <summary>
  340. /// Returns the hash code for this instance.
  341. /// </summary>
  342. public override int GetHashCode()
  343. {
  344. return typeof(T).GetHashCode() ^ 8510;
  345. }
  346. /// <summary>
  347. /// Indicates whether this instance and other are equal.
  348. /// </summary>
  349. public override bool Equals(Notification<T> other)
  350. {
  351. if (Object.ReferenceEquals(this, other))
  352. return true;
  353. if (Object.ReferenceEquals(other, null))
  354. return false;
  355. return other.Kind == NotificationKind.OnCompleted;
  356. }
  357. /// <summary>
  358. /// Returns a string representation of this instance.
  359. /// </summary>
  360. public override string ToString()
  361. {
  362. return "OnCompleted()";
  363. }
  364. /// <summary>
  365. /// Invokes the observer's method corresponding to the notification.
  366. /// </summary>
  367. /// <param name="observer">Observer to invoke the notification on.</param>
  368. public override void Accept(IObserver<T> observer)
  369. {
  370. if (observer == null)
  371. throw new ArgumentNullException("observer");
  372. observer.OnCompleted();
  373. }
  374. /// <summary>
  375. /// Invokes the observer's method corresponding to the notification and returns the produced result.
  376. /// </summary>
  377. /// <param name="observer">Observer to invoke the notification on.</param>
  378. /// <returns>Result produced by the observation.</returns>
  379. public override TResult Accept<TResult>(IObserver<T, TResult> observer)
  380. {
  381. if (observer == null)
  382. throw new ArgumentNullException("observer");
  383. return observer.OnCompleted();
  384. }
  385. /// <summary>
  386. /// Invokes the delegate corresponding to the notification.
  387. /// </summary>
  388. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  389. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  390. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  391. public override void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted)
  392. {
  393. if (onNext == null)
  394. throw new ArgumentNullException("onNext");
  395. if (onError == null)
  396. throw new ArgumentNullException("onError");
  397. if (onCompleted == null)
  398. throw new ArgumentNullException("onCompleted");
  399. onCompleted();
  400. }
  401. /// <summary>
  402. /// Invokes the delegate corresponding to the notification and returns the produced result.
  403. /// </summary>
  404. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  405. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  406. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  407. /// <returns>Result produced by the observation.</returns>
  408. public override TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted)
  409. {
  410. if (onNext == null)
  411. throw new ArgumentNullException("onNext");
  412. if (onError == null)
  413. throw new ArgumentNullException("onError");
  414. if (onCompleted == null)
  415. throw new ArgumentNullException("onCompleted");
  416. return onCompleted();
  417. }
  418. }
  419. /// <summary>
  420. /// Determines whether the current Notification&lt;T&gt; object has the same observer message payload as a specified Notification&lt;T&gt; value.
  421. /// </summary>
  422. /// <param name="other">An object to compare to the current Notification&lt;T&gt; object.</param>
  423. /// <returns>true if both Notification&lt;T&gt; objects have the same observer message payload; otherwise, false.</returns>
  424. /// <remarks>
  425. /// Equality of Notification&lt;T&gt; objects is based on the equality of the observer message payload they represent, including the notification Kind and the Value or Exception (if any).
  426. /// This means two Notification&lt;T&gt; objects can be equal even though they don't represent the same observer method call, but have the same Kind and have equal parameters passed to the observer method.
  427. /// In case one wants to determine whether two Notification&lt;T&gt; objects represent the same observer method call, use Object.ReferenceEquals identity equality instead.
  428. /// </remarks>
  429. public abstract bool Equals(Notification<T> other);
  430. /// <summary>
  431. /// Determines whether the two specified Notification&lt;T&gt; objects have the same observer message payload.
  432. /// </summary>
  433. /// <param name="left">The first Notification&lt;T&gt; to compare, or null.</param>
  434. /// <param name="right">The second Notification&lt;T&gt; to compare, or null.</param>
  435. /// <returns>true if the first Notification&lt;T&gt; value has the same observer message payload as the second Notification&lt;T&gt; value; otherwise, false.</returns>
  436. /// <remarks>
  437. /// Equality of Notification&lt;T&gt; objects is based on the equality of the observer message payload they represent, including the notification Kind and the Value or Exception (if any).
  438. /// This means two Notification&lt;T&gt; objects can be equal even though they don't represent the same observer method call, but have the same Kind and have equal parameters passed to the observer method.
  439. /// In case one wants to determine whether two Notification&lt;T&gt; objects represent the same observer method call, use Object.ReferenceEquals identity equality instead.
  440. /// </remarks>
  441. public static bool operator ==(Notification<T> left, Notification<T> right)
  442. {
  443. if (object.ReferenceEquals(left, right))
  444. return true;
  445. if ((object)left == null || (object)right == null)
  446. return false;
  447. return left.Equals(right);
  448. }
  449. /// <summary>
  450. /// Determines whether the two specified Notification&lt;T&gt; objects have a different observer message payload.
  451. /// </summary>
  452. /// <param name="left">The first Notification&lt;T&gt; to compare, or null.</param>
  453. /// <param name="right">The second Notification&lt;T&gt; to compare, or null.</param>
  454. /// <returns>true if the first Notification&lt;T&gt; value has a different observer message payload as the second Notification&lt;T&gt; value; otherwise, false.</returns>
  455. /// <remarks>
  456. /// Equality of Notification&lt;T&gt; objects is based on the equality of the observer message payload they represent, including the notification Kind and the Value or Exception (if any).
  457. /// This means two Notification&lt;T&gt; objects can be equal even though they don't represent the same observer method call, but have the same Kind and have equal parameters passed to the observer method.
  458. /// In case one wants to determine whether two Notification&lt;T&gt; objects represent a different observer method call, use Object.ReferenceEquals identity equality instead.
  459. /// </remarks>
  460. public static bool operator !=(Notification<T> left, Notification<T> right)
  461. {
  462. return !(left == right);
  463. }
  464. /// <summary>
  465. /// Determines whether the specified System.Object is equal to the current Notification&lt;T&gt;.
  466. /// </summary>
  467. /// <param name="obj">The System.Object to compare with the current Notification&lt;T&gt;.</param>
  468. /// <returns>true if the specified System.Object is equal to the current Notification&lt;T&gt;; otherwise, false.</returns>
  469. /// <remarks>
  470. /// Equality of Notification&lt;T&gt; objects is based on the equality of the observer message payload they represent, including the notification Kind and the Value or Exception (if any).
  471. /// This means two Notification&lt;T&gt; objects can be equal even though they don't represent the same observer method call, but have the same Kind and have equal parameters passed to the observer method.
  472. /// In case one wants to determine whether two Notification&lt;T&gt; objects represent the same observer method call, use Object.ReferenceEquals identity equality instead.
  473. /// </remarks>
  474. public override bool Equals(object obj)
  475. {
  476. return Equals(obj as Notification<T>);
  477. }
  478. /// <summary>
  479. /// Invokes the observer's method corresponding to the notification.
  480. /// </summary>
  481. /// <param name="observer">Observer to invoke the notification on.</param>
  482. public abstract void Accept(IObserver<T> observer);
  483. /// <summary>
  484. /// Invokes the observer's method corresponding to the notification and returns the produced result.
  485. /// </summary>
  486. /// <typeparam name="TResult">The type of the result returned from the observer's notification handlers.</typeparam>
  487. /// <param name="observer">Observer to invoke the notification on.</param>
  488. /// <returns>Result produced by the observation.</returns>
  489. public abstract TResult Accept<TResult>(IObserver<T, TResult> observer);
  490. /// <summary>
  491. /// Invokes the delegate corresponding to the notification.
  492. /// </summary>
  493. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  494. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  495. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  496. public abstract void Accept(Action<T> onNext, Action<Exception> onError, Action onCompleted);
  497. /// <summary>
  498. /// Invokes the delegate corresponding to the notification and returns the produced result.
  499. /// </summary>
  500. /// <typeparam name="TResult">The type of the result returned from the notification handler delegates.</typeparam>
  501. /// <param name="onNext">Delegate to invoke for an OnNext notification.</param>
  502. /// <param name="onError">Delegate to invoke for an OnError notification.</param>
  503. /// <param name="onCompleted">Delegate to invoke for an OnCompleted notification.</param>
  504. /// <returns>Result produced by the observation.</returns>
  505. public abstract TResult Accept<TResult>(Func<T, TResult> onNext, Func<Exception, TResult> onError, Func<TResult> onCompleted);
  506. /// <summary>
  507. /// Returns an observable sequence with a single notification, using the immediate scheduler.
  508. /// </summary>
  509. /// <returns>The observable sequence that surfaces the behavior of the notification upon subscription.</returns>
  510. public IObservable<T> ToObservable()
  511. {
  512. return this.ToObservable(ImmediateScheduler.Instance);
  513. }
  514. /// <summary>
  515. /// Returns an observable sequence with a single notification.
  516. /// </summary>
  517. /// <param name="scheduler">Scheduler to send out the notification calls on.</param>
  518. /// <returns>The observable sequence that surfaces the behavior of the notification upon subscription.</returns>
  519. public IObservable<T> ToObservable(IScheduler scheduler)
  520. {
  521. if (scheduler == null)
  522. throw new ArgumentNullException("scheduler");
  523. return new AnonymousObservable<T>(observer => scheduler.Schedule(() =>
  524. {
  525. this.Accept(observer);
  526. if (this.Kind == NotificationKind.OnNext)
  527. observer.OnCompleted();
  528. }));
  529. }
  530. }
  531. /// <summary>
  532. /// Provides a set of static methods for constructing notifications.
  533. /// </summary>
  534. public static class Notification
  535. {
  536. /// <summary>
  537. /// Creates an object that represents an OnNext notification to an observer.
  538. /// </summary>
  539. /// <typeparam name="T">The type of the elements received by the observer. Upon dematerialization of the notifications into an observable sequence, this type is used as the element type for the sequence.</typeparam>
  540. /// <param name="value">The value contained in the notification.</param>
  541. /// <returns>The OnNext notification containing the value.</returns>
  542. public static Notification<T> CreateOnNext<T>(T value)
  543. {
  544. return new Notification<T>.OnNextNotification(value);
  545. }
  546. /// <summary>
  547. /// Creates an object that represents an OnError notification to an observer.
  548. /// </summary>
  549. /// <typeparam name="T">The type of the elements received by the observer. Upon dematerialization of the notifications into an observable sequence, this type is used as the element type for the sequence.</typeparam>
  550. /// <param name="error">The exception contained in the notification.</param>
  551. /// <returns>The OnError notification containing the exception.</returns>
  552. /// <exception cref="ArgumentNullException"><paramref name="error"/> is null.</exception>
  553. public static Notification<T> CreateOnError<T>(Exception error)
  554. {
  555. if (error == null)
  556. throw new ArgumentNullException("error");
  557. return new Notification<T>.OnErrorNotification(error);
  558. }
  559. /// <summary>
  560. /// Creates an object that represents an OnCompleted notification to an observer.
  561. /// </summary>
  562. /// <typeparam name="T">The type of the elements received by the observer. Upon dematerialization of the notifications into an observable sequence, this type is used as the element type for the sequence.</typeparam>
  563. /// <returns>The OnCompleted notification.</returns>
  564. public static Notification<T> CreateOnCompleted<T>()
  565. {
  566. return new Notification<T>.OnCompletedNotification();
  567. }
  568. }
  569. }
  570. #pragma warning restore 0659
  571. #pragma warning restore 0661