Home > Net >  Dictionary of derived objects
Dictionary of derived objects

Time:05-12

I have a config with thousands of EnumValues and I parse them in runtime

void DoSmth()
{
    foreach (var line in configLines)
    {
        var myEnumValue = (MyEnum) Enum.Parse(line);
        ...
    }
}

and I can improve perfomance by creating a map between a string from the config and an actual enumValue

Dictionary<string, MyEnum> dict = new();
void DoSmth()
{
    foreach (var line in configLines)
    {
        if (!dict.ContainsKey(line)
            dict.Add(line, (MyEnum) Enum.Parse(typeof(MyEnum), line));
        var myEnumValue = dict[line];
        ...
    }
}

Q: Is there any way (maybe using some co/contravariance magic) to create a generic function so it could create such dictionaries dynamically to avoid writing the same caching code over and over again?

e.g.

void DoSmth()
{
    foreach (var line in configLines)
    {
        var myEnumValue = MyExtensions.Parse<MyEnum>(line);
        ...
    }
}
class MyExtensions
{
    Dictionary<Type, Dictionary<string, EnumValue> _cachedEnumValues; // < EnumValue type not exists, so how to?

    public T Parse<T>(string s) where T : Enum
    {
        if (!_cachedEnumValues.ContansKey(typeof(T))
            _cachedEnumValues.Add(typeof(T), new Dictionary<string, T>();

        if (!_cachedEnumValues[typeof(T)].ContansKey(s))
            _cachedEnumValues[typeof(T)].Add(s, (MyEnum) Enum.Parse(typeof(MyEnum), s);

        return _cachedEnumValues[typeof(T)][s];
    }
}

CodePudding user response:

Sure:

public sealed class EnumHelper<T> where T : Enum
{
    private static readonly ConcurrentDictionary<string, T> Cache = new ConcurrentDictionary<string, T>(StringComparer.OrdinalIgnoreCase);

    public static T Parse(string s)
    {
        return Cache.GetOrAdd(s, k => (T)Enum.Parse(typeof(T), k));
    }
}

Usage:

var t = EnumHelper<SearchOption>.Parse(SearchOption.AllDirectories.ToString());
  • Related