title: Remove duplicates from list of object
body: <p>I have MyObject with field: id, a, b, c, e, f
  and I have List with 500 000 items, now how can I remove all duplicate items with of the same value of the parameter a, c, f? </p>
  
  <p>I am looking for only the fastest and most efficient method. </p>
  
  <p><strong>UPDATE</strong><br>
  I implemented comparator</p>
  
  <p>Fields in my class are of different types so I use <code>ToString()</code>. It is good way?<br>
  <code>IdLoc</code>, <code>IdMet</code>, <code>Ser</code> are long?<br>
  <code>Value</code> is Object<br>
  <code>IdDataType</code> is long  </p>
  
  <pre><code>class Comparer : IEqualityComparer&lt;MyObject&gt;
  {
      public bool Equals(MyObject x, MyObject y)
      {                
          return x.IdLoc == y.IdLoc &amp;&amp; x.IdMet == y.IdMet &amp;&amp; x.Ser == y.Ser &amp;&amp;
                 x.IdDataType == y.IdDataType &amp;&amp; x.Time == y.Time &amp;&amp; x.Value == y.Value;
      }
  
      public int GetHashCode(MyObject obj)
      {
          string idLoc = obj.IdLoc.HasValue ? obj.IdLoc.ToString() : String.Empty;
          string idMet = obj.IdMet.HasValue ? obj.IdMet.ToString() : String.Empty;
          string ser = obj.Ser.HasValue ? obj.Ser.ToString() : String.Empty;
          string value = obj.Value != null ?  obj.Value.ToString() : String.Empty;
  
          return (idLoc + idMet + ser + value + obj.IdDataType.ToString() + obj.Time.ToString()).GetHashCode();
      }
  }
  </code></pre>
  
  <p>Removing duplicates<br>
  Elements 566 890<br>
  1) Time: 2 sec</p>
  
  <pre><code>DateTime start = DateTime.Now;
  List&lt;MyObject&gt; removed = retValTmp.Distinct(new Comparer()).ToList();
  double sec = Math.Round((DateTime.Now - start).TotalSeconds, 3);
  </code></pre>
  
  <p>2) Time: 1.5 sec</p>
  
  <pre><code>start = DateTime.Now;
  List&lt;MyObject&gt; retList = new List&lt;MyObject&gt;();
  HashSet&lt;MyObject&gt; removed2 = new HashSet&lt;MyObject&gt;(new Comparer());
  foreach (var item in retValTmp)
  {
      if (!removed2.Contains(item))
      {
          removed2.Add(item);
          retList.Add(item);
      }
  }                
  double sec2 = Math.Round((DateTime.Now - start).TotalSeconds, 3);
  </code></pre>
  
  <p>4) Also I tried out this way:  </p>
  
  <pre><code>start = DateTime.Now;
  
  var removed3 = retValTmp.Select(myObj =&gt; new { myObj.IdLoc, myObj.IdMet, myObj.Ser, myObj.Value, myObj.IdDataType, myObj.Time }).Distinct().ToList();
  
  double sec3 = Math.Round((DateTime.Now - start).TotalSeconds, 3);
  </code></pre>
  
  <p>Time: 0.35 sec<br>
  but returned list is not in my class, and why the number of elements in the list of 1 and 2 is different than the list of 3?</p>
  
  <p><strong>UPDATE2</strong>  </p>
  
  <pre><code>public int GetDataHashCode(MyObject obj)
  {
      long idLoc = obj.IdLoc.HasValue ? obj.IdLoc.Value : 0;
      long idMet = obj.IdMet.HasValue ? obj.IdMet.Value : 0;
      long ser = obj.SerHasValue ? obj.Ser.Value : 0;
      int valueHash = 0;
      if (obj.Value != null)
          valueHash = obj.Value.GetHashCode();
      else
          valueHash = valueHash.GetHashCode();
  
      return (idLoc.GetHashCode() + idMet.GetHashCode() + ser.GetHashCode() + valueHash  + obj.IdDataType.GetHashCode() + obj.Time.GetHashCode()).GetHashCode();
  }
  </code></pre>
  
  <p>use:  </p>
  
  <pre><code>foreach (MyObject daItem in retValTmp)
  {
      int key = GetDataHashCode(daItem);
      if (!clearDict.ContainsKey(key))
          clearDict.Add(key, daItem);
  } 
  </code></pre>
  
  <p>Element: 750 000<br>
  Time: <strong><em>0.23 sec!</em></strong> </p>