Reputation: 171
I have a Dictionary<dynamic, string>
and when checking if the dictionary contains a key, if the key is a string I would like to ignore the case. Is this possible?
Upvotes: 1
Views: 10339
Reputation: 460
You could add an extension to the Dictionary
which determines if the key is of type string, and if so, uses case insensitive comparison; otherwise, it uses the default comparison.
public static class DictionaryExtension
{
public static bool ContainsKeyIgnoreCase<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
{
bool? keyExists;
var keyString = key as string;
if (keyString != null)
{
// Key is a string.
// Using string.Equals to perform case insensitive comparison of the dictionary key.
keyExists =
dictionary.Keys.OfType<string>()
.Any(k => string.Equals(k, keyString, StringComparison.InvariantCultureIgnoreCase));
}
else
{
// Key is any other type, use default comparison.
keyExists = dictionary.ContainsKey(key);
}
return keyExists ?? false;
}
}
You can then use it like this:
var foo = new Foo();
var dictionary =
new Dictionary<dynamic, string>
{
{ 1, "One" }, // key is numeric
{ "Two", "Two" }, // key is string
{ foo, "Foo" } // key is object
};
dictionary.ContainsKeyIgnoreCase("two"); // Returns true
dictionary.ContainsKeyIgnoreCase("TwO"); // Returns true
dictionary.ContainsKeyIgnoreCase("aBc"); // Returns false
dictionary.ContainsKeyIgnoreCase(1); // Returns true
dictionary.ContainsKeyIgnoreCase(2); // Returns false
dictionary.ContainsKeyIgnoreCase(foo); // Returns true
dictionary.ContainsKeyIgnoreCase(new Foo()); // Returns false
Note:
The extension example above is using StringComparer.InvariantCultureIgnoreCase. You may need to modify the comparison for your needs.
Upvotes: 3
Reputation:
There's no reasonable way you could implement a case-insensitive get on a case-sensitive hash map.
Although you can create a new case-insensitive dictionary with the contents of an existing case-sensitive dictionary (if you're sure there are no case collisions):-
var oldDictionary = ...;
var comparer = StringComparer.OrdinalIgnoreCase;
var newDictionary = new Dictionary<string, int>(oldDictionary, comparer);
Let me know, if it works.
Upvotes: 2