Question

I noticed when trying to code a CLR procedure for SQL Server that HashSet is not allowed due to being attributed with [HostProtectionAttribute(SecurityAction.LinkDemand, MayLeakOnAbort = true)]. SQL Server CLR procedures do not allow the use of objects where MayLeakOnAbort is set. Okay, so there are some classes to avoid in CLR procedures, and maybe even think twice about using outside of CLR procedures. The strange thing is that Dictionary<K,V> is not similarly restricted. Now based on my understanding of what a HashSet is and what a Dictionary is, I expect that a Dictionary should have all the complexity of a Hashset and then some. Why is it, then, that Dictionary is not similarly restricted? I'm doing my "think twice about using HashSet<T>" and seriously considering using a Dictionary instead even though I'm not writing a CLR procedure and need nothing more than a collection that can be quickly tested for membership of a complex key (object reference for an object that has no comparison, hashing or equality interfaces defined). Am I better off using a Hashset or Dictionary? Is Hashset different in that it will allow the use of classes with no comparison or equality interfaces based purely on memory addresses or something which might be why a HashSet is less "clean"?

Was it helpful?

Solution

HashSet<T> contains methods such as IntersectWith that are implemented with unsafe code using stackalloc. Dictionary<TKey, TValue> does not contain any such methods. While it's possible to mark your own assembly as unsafe, and avoid the risky methods, I've simply given up and used Dictionary<T, bool> in SQL CLR functions, where all values are true, for precisely this reason.

OTHER TIPS

Dictionary is based on HashTable, rather than HashSet. While they are conceptually very similar, the implementation of HashSet includes some unsafe methods, whereas HashTable and Dictionary do not.

Dictionary uses a HashTable primarily as a means of speeding searches of the keyspace. Given an efficient implementation of GetHashCode() on the type used for your dictionary key, lookups in a dictionary are best-case constant time and worst-case linear time.

The HashSet is a collection for storing unique values only (no keying mechanism), and requires a proper implementation of GetHashCode on your class to function properly.

HashTables and Dictionaries are used for looking up values by a key. HashSets are used solely for maintaining a set of unique objects and do not have a keying mechanism.

If you don't need a uniqueness guarantee, or the other functions provided by something that implements ISet, there's no real reason to use a HashSet instead of an array or list.

If you need the ability to get your items out of the collection by a key, use a HashTable or Dictionary (Dictionary is preferred, since it is generic-aware and thus you're not constantly boxing/unboxing everything).

See these links for explanations:

http://msdn.microsoft.com/en-us/library/bb397727(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/4yh14awz(v=vs.110).aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top