Timestamped.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. using System.Globalization;
  6. namespace System.Reactive
  7. {
  8. /// <summary>
  9. /// Represents value with a timestamp on it.
  10. /// The timestamp typically represents the time the value was received, using an IScheduler's clock to obtain the current time.
  11. /// </summary>
  12. /// <typeparam name="T">The type of the value being timestamped.</typeparam>
  13. #if !NO_SERIALIZABLE
  14. [Serializable]
  15. #endif
  16. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Timestamped", Justification = "Reviewed and agreed upon.")]
  17. public struct Timestamped<T> : IEquatable<Timestamped<T>>
  18. {
  19. private readonly DateTimeOffset _timestamp;
  20. private readonly T _value;
  21. /// <summary>
  22. /// Constructs a timestamped value.
  23. /// </summary>
  24. /// <param name="value">The value to be annotated with a timestamp.</param>
  25. /// <param name="timestamp">Timestamp associated with the value.</param>
  26. public Timestamped(T value, DateTimeOffset timestamp)
  27. {
  28. _timestamp = timestamp;
  29. _value = value;
  30. }
  31. /// <summary>
  32. /// Gets the value.
  33. /// </summary>
  34. public T Value
  35. {
  36. get { return _value; }
  37. }
  38. /// <summary>
  39. /// Gets the timestamp.
  40. /// </summary>
  41. public DateTimeOffset Timestamp
  42. {
  43. get { return _timestamp; }
  44. }
  45. /// <summary>
  46. /// Determines whether the current Timestamped&lt;T&gt; value has the same Value and Timestamp as a specified Timestamped&lt;T&gt; value.
  47. /// </summary>
  48. /// <param name="other">An object to compare to the current Timestamped&lt;T&gt; value.</param>
  49. /// <returns>true if both Timestamped&lt;T&gt; values have the same Value and Timestamp; otherwise, false.</returns>
  50. public bool Equals(Timestamped<T> other)
  51. {
  52. return other.Timestamp.Equals(Timestamp) && EqualityComparer<T>.Default.Equals(Value, other.Value);
  53. }
  54. /// <summary>
  55. /// Determines whether the two specified Timestamped&lt;T&gt; values have the same Value and Timestamp.
  56. /// </summary>
  57. /// <param name="first">The first Timestamped&lt;T&gt; value to compare.</param>
  58. /// <param name="second">The second Timestamped&lt;T&gt; value to compare.</param>
  59. /// <returns>true if the first Timestamped&lt;T&gt; value has the same Value and Timestamp as the second Timestamped&lt;T&gt; value; otherwise, false.</returns>
  60. public static bool operator ==(Timestamped<T> first, Timestamped<T> second)
  61. {
  62. return first.Equals(second);
  63. }
  64. /// <summary>
  65. /// Determines whether the two specified Timestamped&lt;T&gt; values don't have the same Value and Timestamp.
  66. /// </summary>
  67. /// <param name="first">The first Timestamped&lt;T&gt; value to compare.</param>
  68. /// <param name="second">The second Timestamped&lt;T&gt; value to compare.</param>
  69. /// <returns>true if the first Timestamped&lt;T&gt; value has a different Value or Timestamp as the second Timestamped&lt;T&gt; value; otherwise, false.</returns>
  70. public static bool operator !=(Timestamped<T> first, Timestamped<T> second)
  71. {
  72. return !first.Equals(second);
  73. }
  74. /// <summary>
  75. /// Determines whether the specified System.Object is equal to the current Timestamped&lt;T&gt;.
  76. /// </summary>
  77. /// <param name="obj">The System.Object to compare with the current Timestamped&lt;T&gt;.</param>
  78. /// <returns>true if the specified System.Object is equal to the current Timestamped&lt;T&gt;; otherwise, false.</returns>
  79. public override bool Equals(object obj)
  80. {
  81. if (!(obj is Timestamped<T>))
  82. return false;
  83. var other = (Timestamped<T>)obj;
  84. return this.Equals(other);
  85. }
  86. /// <summary>
  87. /// Returns the hash code for the current Timestamped&lt;T&gt; value.
  88. /// </summary>
  89. /// <returns>A hash code for the current Timestamped&lt;T&gt; value.</returns>
  90. public override int GetHashCode()
  91. {
  92. var valueHashCode = Value == null ? 1979 : Value.GetHashCode();
  93. return _timestamp.GetHashCode() ^ valueHashCode;
  94. }
  95. /// <summary>
  96. /// Returns a string representation of the current Timestamped&lt;T&gt; value.
  97. /// </summary>
  98. /// <returns>String representation of the current Timestamped&lt;T&gt; value.</returns>
  99. public override string ToString()
  100. {
  101. return String.Format(CultureInfo.CurrentCulture, "{0}@{1}", Value, Timestamp);
  102. }
  103. }
  104. /// <summary>
  105. /// A helper class with a factory method for creating Timestamped&lt;T&gt; instances.
  106. /// </summary>
  107. public static class Timestamped
  108. {
  109. /// <summary>
  110. /// Creates an instance of a Timestamped&lt;T&gt;. This is syntactic sugar that uses type inference
  111. /// to avoid specifying a type in a constructor call, which is very useful when using anonymous types.
  112. /// </summary>
  113. /// <param name="value">The value to be annotated with a timestamp.</param>
  114. /// <param name="timestamp">Timestamp associated with the value.</param>
  115. /// <returns>Creates a new timestamped value.</returns>
  116. public static Timestamped<T> Create<T>(T value, DateTimeOffset timestamp)
  117. {
  118. return new Timestamped<T>(value, timestamp);
  119. }
  120. }
  121. }