title: Is it ok to have a GUID private property in a class in order to use it in GetHashCode override?
body: <p>Is it OK to have a GUID private property in a class in order to use it in GetHashCode override?</p>
  
  <p>Something like:</p>
  
  <pre><code>public class Voucher : IComparable&lt;Voucher&gt;, IComparable, IEquatable&lt;Voucher&gt;
  {
      private Guid? _guid;
  
  
      private Guid Guid
      {
          get
          {
              return _guid ?? (_guid = Guid.NewGuid()).GetValueOrDefault();
          }
      }
      public int Id { get; private set; }
      public string Number { get; private set; }
      public DateTime Date { get; private set; }
  
  
  
      public Voucher(string number, DateTime date)
      {
          Number = number;
          Date = date;
      }
  
      public Voucher(int id, string number, DateTime date)
          : this(number, date)
      {
          Id = id;
      }
  
  
  
      public override bool Equals(object obj)
      {
          return Equals(obj as Voucher);
      }
  
      public override int GetHashCode()
      {
          return Guid.GetHashCode();
      }
  
      public override string ToString()
      {
          return String.Format("[{0}] - [{1:dd/MM/yyyy}]", Number, Date);
      }
  
  
  
      #region IComparable&lt;Voucher&gt; Members
  
      public int CompareTo(Voucher other)
      {
          if (other == null)
              return -1;
  
          if (Date != other.Date)
              return Date.CompareTo(other.Date);
          else
              return Number.CompareTo(other.Number);
      }
  
      #endregion
  
      #region IComparable Members
  
      public int CompareTo(object obj)
      {
          return CompareTo(obj as Voucher);
      }
  
      #endregion
  
      #region IEquatable&lt;Voucher&gt; Members
  
      public bool Equals(Voucher other)
      {
          if (other != null)
              return (Number == other.Number) &amp;&amp; (Date == other.Date);
  
          return false;
      }
  
      #endregion
  }
  </code></pre>
  
  <p>Yesterday I found out that in order to override GetHashCode we have to use only immutable members/fields of the class.</p>
  
  <p>For many of my cases that is only the Id that is produced by identity of the Sql Server and for new instances that is 0.</p>
  
  <p>So for many new objects (not persisted to database thus Id is 0) object hash code is the same. Correct?</p>
  
  <p>Would it be a solution to use GUID like the example above?
  Thanks.</p>
  
  <p><strong>EDIT</strong>
  Class after comments</p>
  
  <p>So after your comments I've changed it to:</p>
  
  <pre><code>public class Voucher : IComparable&lt;Voucher&gt;, IComparable, IEquatable&lt;Voucher&gt;
      {
          public int Id { get; private set; }
          public string Number { get; private set; }
          public DateTime Date { get; private set; }
  
  
  
          public Voucher(string number, DateTime date)
          {
              Number = number;
              Date = date;
          }
  
          public Voucher(int id, string number, DateTime date)
              : this(number, date)
          {
              Id = id;
          }
  
  
  
          public override bool Equals(object obj)
          {
              return Equals(obj as Voucher);
          }
  
          public override int GetHashCode()
          {
              return Number.GetHashCode() ^ Date.GetHashCode();
          }
  
          public override string ToString()
          {
              return String.Format("[{0}] - [{1:dd/MM/yyyy}]", Number, Date);
          }
  
  
  
          #region IComparable&lt;Voucher&gt; Members
  
          public int CompareTo(Voucher other)
          {
              if (other == null)
                  return -1;
  
              if (Date != other.Date)
                  return Date.CompareTo(other.Date);
              else
                  return Number.CompareTo(other.Number);
          }
  
          #endregion
  
          #region IComparable Members
  
          public int CompareTo(object obj)
          {
              return CompareTo(obj as Voucher);
          }
  
          #endregion
  
          #region IEquatable&lt;Voucher&gt; Members
  
          public bool Equals(Voucher other)
          {
              if (other != null)
                  return (Number == other.Number) &amp;&amp; (Date == other.Date);
  
              return false;
          }
  
          #endregion
      }
  </code></pre>
  
  <p>I guess that this is OK since Voucher is immutable.</p>
  
  <p>But if members Number and Date were not immutable and could be accessed - altered outside the class? Then what is the solution?
  Is it enough just to document the class something like "Cannot be used in HashCode depended Lists"?</p>