Something that’s always bothered me a little about the generic dictionary support in .NET is that it’s, by default, case sensitive. I’d never really contemplated it much more than that until today, when I really needed a dictionary that supported a fast, case insensitive lookup.
At first, I used a list, and the FirstOrDefault function along with a lambda expression. It worked, but I soon realized it was wretchedly slow.
I knew that surely, there was a way to get case insensitive lookups with a generic dictionary, but I’d never really gone looking for it. But a little searching later, and I’d found the answer.
Public Sub Test() Dim d = New Dictionary(Of String, String)(StringComparer.CurrentCultureIgnoreCase) d.Add("John", "JohnTest") d.Add("Bob", "BobTest") d.Add("Bill", "BillTest") d.Add("Zack", "ZackTest") Debug.Print(d.Keys.Contains("ZACK")) Debug.Print(d("bill")) End Sub
You must specify an IEqualityComparer object as part of the constructor, and the object to use can be easily obtained from the StringComparer factory object., as show above.
Give it a shot with and without the (StringComparer.CurrentCultureIgnoreCase) clause.
Even better. If you’re defining your own strongly typed dictionary based on the generic dictionary, you can force the comparer in your constructor, so that instances of your dictionary will always use the right comparer; code that instantiates your dictionary won’t have to bother with (or remember to supply) the StringComparer object.
Public Class StringDict Inherits Dictionary(Of String, String) Public Sub New() MyBase.New(StringComparer.CurrentCultureIgnoreCase) End Sub End Class Public Sub Test2() Dim d = New StringDict d.Add("John", "JohnTest") d.Add("Bob", "BobTest") d.Add("Bill", "BillTest") d.Add("Zack", "ZackTest") Debug.Print(d.Keys.Contains("ZACK")) Debug.Print(d("bill")) End Sub
It may not be new, but it’s new to me, and awfully nice to know!