There is a coding anti-pattern I've noticed (while using .Net). You declare a data class, which is supposed to have a dictionary field (or get/set Property), and lets call it 'Properties', for the sake of example. It has a string key type.
public System.Collections.Generic.Dictionary<string, object> Properties { get; set; }
We might want to use it like a plain old data class. So, we can deserialize JSON or SQL rows or whatever, to fill in the properties dictionary. By seemingly good luck, our JSON serializer understands the dictionary type and can do that pretty well. BUT (here comes the problem...) in our business logic, we want this dictionary to be case-insensitive with how it treats keys.
"OK, no problem," you say. "Dictionaries can do that. Every time we write code that initializes a dictionary on the class, we will just do this:
Properties = new Dictionary<string, object>(StringComparer.InvariantCultureIgnoreCase)
Well, do you see the problem with this? Because we put a public setter on there. Anyone can call this dictionary setter and put a case-sensitive dictionary onto our object instead. And Murphy assures us they will; not out of bad intentions, mind you, but because it is just all too easy to forget the optional StringComparer parameter to Dictionary.
And even worse, we have code that we don't own, in our JSON deserializer, or object mapping framework, which doesn't bother to use a StringComparer. Or perhaps it just chooses the wrong one, for instance StringComparer.CurrentCultureIgnoreCase, or OrdinalIgnoreCase. THis is clearly a disaster waiting to happen. What should we do about this?