brenton
brenton

Reputation: 558

Generic Dictionary Comparison

I have a problem I can't seem to wrap my head around. I am creating a class to hold a dictionary of items that have generic types. The problem I'm faced with is needed to force this dictionary to be InvariantCultureIgnoreCase if the index type is a string.

For example:

public class Cache<TIndex, TItem>
{
    protected IDictionary<TIndex, TItem> _cache { get; set; }

    public Cache()
    {
        this._cache = new Dictionary<TIndex, TItem>();
    }

    public bool Exists(TIndex index)
    {
        if (!_cache.ContainsKey(index))
        {
            //....do other stuff here
            this._cache.Add(databaseResult.Key, databaseResult.Value);
            return false;
        }
        return true;
    }
} 

So the first problem was dealing with strings that had various capitalization; I solved this by forcing the data to be upper-case. Now, however, I've found that there are some characters which are culture specific, so without the invariant culture switch, ContainsKey will return false.

I've tried creating a new IEqualityComparer, but that never gets fired. Any ideas?

Upvotes: 3

Views: 152

Answers (2)

Tim
Tim

Reputation: 15237

Here's a fully functional version of what I THINK you're asking for (I had to add a Set function, otherwise it is based on your own code). It is, as the if/Console.WriteLine checks show, ignoring case. If this isn't what you're looking for, please clarify your question further.

class Program
{
    static void Main(string[] args)
    {

        Cache<string, string> stringCache = new Cache<string, string>();

        stringCache.Set("A String Index", "A String Item");

        if (stringCache.Exists("A String Index"))
            Console.WriteLine("Title Case exists");

        if (stringCache.Exists("A STRING INDEX"))
            Console.WriteLine("All Caps Exists");

        if (stringCache.Exists("a string index"))
            Console.WriteLine("All Lowercase Exists");
    }
}

class Cache<TIndex, TItem>
{
    private IDictionary<TIndex, TItem> _cache { get; set; }

    public Cache()
    {
        if (typeof(TIndex) == typeof(string))
        {
            _cache = new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase);
        }
        else
        {
            _cache = new Dictionary<TIndex, TItem>();
        }
    }

    public void Set(TIndex index, TItem item)
    {
        _cache[index] = item;
    }

    public bool Exists(TIndex index)
    {
        if (!_cache.ContainsKey(index))
        {
            return false;
        }
        return true;
    }

}

Upvotes: 1

Wagner DosAnjos
Wagner DosAnjos

Reputation: 6374

Please try the following:

public Cache()
{
    if (typeof(TIndex) == typeof(string))
    {
        this._cache = new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase);
    }
    else
    {
        this._cache = new Dictionary<TIndex, TItem>();
    }
}

Or (with ternary operator):

public Cache()
{
    this._cache = typeof(TIndex) == typeof(string)
                ? new Dictionary<TIndex, TItem>((IEqualityComparer<TIndex>)StringComparer.InvariantCultureIgnoreCase)
                : new Dictionary<TIndex, TItem>();
}

Or (really short, as suggested by @Rawling):

public Cache()
{
    this._cache = new Dictionary<TIndex, TItem>(StringComparer.InvariantCultureIgnoreCase as IEqualityComparer<TIndex>);
}

Upvotes: 5

Related Questions