简体   繁体   中英

How can I make dictionary case insensitive

I am trying to make Dictionary case insensitive. But, I declare it as a property, how can I make that insensitive.

I know that while defining, I can use it like :

var dict = new Dictionary<string, YourClass>(
        StringComparer.InvariantCultureIgnoreCase);

But, I am defining it in my interface and class respectively like

IDictionary<string, string> dict { get; }
public Dictionary<string, string> dict { get; set; }

How can I make this case insensitive ?

You mentioned that You define it in Your class like:

public Dictionary<string, string> dict { get; set; }

So, instead of using short form for auto properties, use the full form:

Dictionary<string, string> _dict = new Dictionary<string, string>(
    StringComparer.InvariantCultureIgnoreCase);
public Dictionary<string, string> dict
{
    get { return _dict; }
    set { _dict = value; }
}

If You are using C# 6.0, You could also probably even write it using the new auto property initializers syntax:

public Dictionary<string, string> dict { get; set; } = new Dictionary<string, string>(
    StringComparer.InvariantCultureIgnoreCase);

Links:

The only way you could enforce it on the class or interface level is you make a new derived type and use that type.

public class CaseInsensitiveDictionary<TValue> : Dictionary<string, TValue>
{
    public CaseInsensitiveDictionary() : base(StringComparer.InvariantCultureIgnoreCase)
    {
    }
}

Then in your interface you would do

CaseInsensitiveDictionary<YourClass> { get; }

You can't. The comparer is a read-only property ( https://msdn.microsoft.com/en-us/library/ms132092(v=vs.110).aspx ). Declare your comparer during the construction of your object.

Allowing one to change comparers at runtime would be seriously problematic as it could result in sudden key collisions that would require the dictionary to be restructured.

If the case insensitivity is intended to be part of the contract, it sounds like what you really want to be doing is encapsulating this logic inside something else and then exposing that on your interface instead.

Depending on what specific functionality you're trying to expose, something as simple as this might do the trick:

public class CaseInsensitiveIndex
{
    private readonly Dictionary<string, object> _collection = 
        new Dictionary<string, object>();

    public object this[string index]
    {
        get { return _collection[index.ToLower()]; }
        set { _collection[index.ToLower()] = value; }
    }
}

public interface IHasCaseInsensitiveIndex
{
    CaseInsensitiveIndex Index { get; }
}

It seems a little odd to me to be publicly exposing a collection via an interface like this (this feels like it should be an internal implementation detail... but that depends on the context - consider whether your encapsulation needs work) but this is the closest thing to what you're trying to achieve that I can think of.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM