派生对象字典

Dictionary of derived objects

我有一个包含数千个 EnumValue 的配置,我在运行时解析它们

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

我可以通过在配置字符串和实际枚举值之间创建映射来提高性能

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];
        ...
    }
}

问: 有没有什么办法(也许使用一些 co/contravariance 魔法)来创建一个通用函数,这样它就可以动态地创建这样的字典以避免一遍又一遍地编写相同的缓存代码?

例如

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];
    }
}

当然可以:

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));
    }
}

用法:

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