I hadn’t done much (read: anything) with the C# generic HashSet until I recently needed to produce a distinct collection.  As it turns out, HashSet<T> was the perfect tool.

As the following snippet demonstrates, this collection type offers a lot:

  1. // Using HashSet<T>:
  2. // http://www.albahari.com/nutshell/ch07.aspx
  3. var letters = new HashSet<char>("the quick brown fox");
  4.  
  5. Console.WriteLine(letters.Contains('t')); // true
  6. Console.WriteLine(letters.Contains('j')); // false
  7.  
  8. foreach (char c in letters) Console.Write(c); // the quickbrownfx
  9. Console.WriteLine();
  10.  
  11. letters = new HashSet<char>("the quick brown fox");
  12. letters.IntersectWith("aeiou");
  13. foreach (char c in letters) Console.Write(c); // euio
  14. Console.WriteLine();
  15.  
  16. letters = new HashSet<char>("the quick brown fox");
  17. letters.ExceptWith("aeiou");
  18. foreach (char c in letters) Console.Write(c); // th qckbrwnfx
  19. Console.WriteLine();
  20.  
  21. letters = new HashSet<char>("the quick brown fox");
  22. letters.SymmetricExceptWith("the lazy brown fox");
  23. foreach (char c in letters) Console.Write(c); // quicklazy
  24. Console.WriteLine();

The MSDN documentation is a bit light on HashSet<T> documentation but if you search hard enough you can find some interesting information and benchmarks.

But back to that distinct list I needed…

  1. var coderA = new Employee { Id = 1, Name = "Coder A" };
  2. var coderB = new Employee { Id = 2, Name = "Coder B" };
  3. var coderC = new Employee { Id = 3, Name = "Coder C" };
  4.  
  5. // Coder A is being added to both lists
  6. var cSharpCoders = new List<Employee> { coderA, coderB };
  7. var fSharpCoders = new List<Employee> { coderA, coderC };
  8.  
  9. var coders = new HashSet<Employee>();
  10. cSharpCoders.ForEach(x => coders.Add(x));
  11. fSharpCoders.ForEach(x => coders.Add(x));
  12.  
  13. foreach (Employee c in coders) Console.WriteLine(c);
  14. // Returns a unique list set — Coder A Coder B Coder C

The Add Method returns true on success and, you guessed it, false if the item couldn’t be added to the collection.  I’m using the Linq ForEach syntax to add all valid items to the employees HashSet.  It works really great. 

This is just a rough sample, but you may have noticed I’m using Employee, a reference type.  Most samples demonstrate the power of the HashSet with a collection of integers which is kind of cheating.  With value types you don’t have to worry about defining your own equality members.  With reference types, you do.

  1. internal class Employee
  2. {
  3.     public int Id { get; set; }
  4.     public string Name { get; set; }
  5.  
  6.     public override string ToString()
  7.     {
  8.         return Name;
  9.     }
  10.     
  11.     public bool Equals(Employee other)
  12.     {
  13.         if (ReferenceEquals(null, other)) return false;
  14.         if (ReferenceEquals(this, other)) return true;
  15.         return other.Id == Id;
  16.     }
  17.  
  18.     public override bool Equals(object obj)
  19.     {
  20.         if (ReferenceEquals(null, obj)) return false;
  21.         if (ReferenceEquals(this, obj)) return true;
  22.         if (obj.GetType() != typeof (Employee)) return false;
  23.         return Equals((Employee) obj);
  24.     }
  25.  
  26.     public override int GetHashCode()
  27.     {
  28.         return Id;
  29.     }
  30.  
  31.     public static bool operator ==(Employee left, Employee right)
  32.     {
  33.         return Equals(left, right);
  34.     }
  35.  
  36.     public static bool operator !=(Employee left, Employee right)
  37.     {
  38.         return !Equals(left, right);
  39.     }
  40. }

Fortunately, with Resharper, it’s a snap. Click on the class name, ALT+INS and then follow with the handy dialogues.

image

That’s it. Try out the HashSet<T>. It’s good stuff.

11 Comments to “C# HashSet<T>”

  1. Rahul says:

    First of all. Thanks very much for your useful post.

    I just came across your blog and wanted to drop you a note telling you how impressed I was with the

    information you have posted here.

    Please let me introduce you some info related to this post and I hope that it is useful for community.

    There is a good C# resource site, Have alook

    http://CSharpTalk.com

    Thanks again
    Rahul

  2. Ben Griswold says:

    Thanks for the comment and the reference site, Rahul. All the best, Ben

  3. Meenatchi Natarajan says:

    Ben,

    Excellent.Its working as it is supposed to be.
    As u said all the other URLs has an exmaple with int,string example.Hope,only your article has reference type example.Very useful and Most of the application requires this sort of facilities.

  4. Ben Griswold says:

    Hi Meenatchi, Thanks for the comment and I’m glad everything is working for you.

  5. Henri M. says:

    Hi Ben,
    and thanks for the info regarding hashset, and also about resharper. Didn’t know it was in there, great tip.
    First example was very nice.

    But with regards to hashset I just don’t get the second example.
    Might be something I overlook, but as you just add A to naughty and B + C to nice wouldn’t you get the same result in a plain old List?

    Of course if your exampledata was different, it would probably show that the hashset only added unique employees?

    But too me the exampledata sort of missed the point, which is sad as it seems all the working parts are there.

    Anyways, lot’s of good info in the article, and the Resharper tip was also very nice.

    Rgds
    Henri

  6. Pradeep Gupta says:

    Thanks
    Good Article
    Its very helpful.

  7. Ben Griswold says:

    Hi Henri,

    Thank you for your thoughtful comment. You’re absolutely correct — my example, which is supposed to demonstrate how HashSets have the benefit of uniqueness, didn’t demonstrate this feature at all. Yikes! Though it would have made the example a little convoluted since someone should really only be naughty or nice, I should have added Employee A to both lists and then I could have should the Employee HashSet includes a unique list still. I’ll see if I can get the sample updated.

    Thanks again,
    Ben

  8. Ben Griswold says:

    Hi Henri, per your comments, I have updated the example. Thanks again.

  9. Dave says:

    This is the first excellent example of the HashSet I have found anywhere. So many bloggers have provided the most pathetic, contrived and utterless useless examples which add absolutely nothing to someone who is actually trying to get a grasp of this collection. Your post has answered several questions I had about this poorly documented collection. You are a champion! I think I will look in here more often. Be well!

  10. Meenatchi Natarajan says:

    Ben,
    need a help.is it possible to compare a dataset/datatable records using hashset.if yes,please give me an example.

  11. Ben Griswold says:

    @Meenatchi, I am not aware of any relationship between DataSets/DataTables and HashSets. I’m going to have to say no. Sorry.

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>