Search code examples
c#.nethashset

How to retrieve actual item from HashSet<T>?


I've read this question about why it is not possible, but haven't found a solution to the problem.

I would like to retrieve an item from a .NET HashSet<T>. I'm looking for a method that would have this signature:

/// <summary>
/// Determines if this set contains an item equal to <paramref name="item"/>, 
/// according to the comparison mechanism that was used when the set was created. 
/// The set is not changed. If the set does contain an item equal to 
/// <paramref name="item"/>, then the item from the set is returned.
/// </summary>
bool TryGetItem<T>(T item, out T foundItem);

Searching the set for an item with such a method would be O(1). The only way to retrieve an item from a HashSet<T> is to enumerate all items which is O(n).

I haven't find any workaround to this problem other then making my own HashSet<T> or use a Dictionary<K, V>. Any other idea?

Note:
I don't want to check if the HashSet<T> contains the item. I want to get the reference to the item that is stored in the HashSet<T> because I need to update it (without replacing it by another instance). The item I would pass to the TryGetItem would be equal (according to the comparison mechanism that I've passed to the constructor) but it would not be the same reference.


Solution

  • What you're asking for was added to .NET a year ago, and was recently added to .NET 4.7.2:

    In .NET Framework 4.7.2 we have added a few APIs to the standard Collection types that will enable new functionality as follows.

    • ‘TryGetValue‘ is added to SortedSet and HashSet to match the Try pattern used in other collection types.

    The signature is as follows (found in .NET 4.7.2 and above):

        //
        // Summary:
        //     Searches the set for a given value and returns the equal value it finds, if any.
        //
        // Parameters:
        //   equalValue:
        //     The value to search for.
        //
        //   actualValue:
        //     The value from the set that the search found, or the default value of T when
        //     the search yielded no match.
        //
        // Returns:
        //     A value indicating whether the search was successful.
        public bool TryGetValue(T equalValue, out T actualValue);