<Type, List<Type>>类型的字典

4
我希望实现一个包装类,用于映射类型到该类型的通用List的Dictionary。例如:

**Key**               **Value**
typeof(InterfaceA), List<InterfaceA>
typeof(InterfaceB), List<InterfaceB>
typeof(MyClass), List<MyClass>
...

我希望您能使用类型与包装类进行交互。
public void NewEntry<T>()
{
    MyDict.Add(typeof(T), new List<T>());
}

public List<T> GetEntry<T>()
{
    return MyDict[typeof(T)];
}

public void RemoveEntry<T>()
{
    MyDict.Remove(typeof(T));
}

有没有一种优雅的方法来做到这一点?编辑:为了澄清,这是为了让用...
GetEntry<MyInterface>()
    列表中的每一项都保证遵循MyInterface的约定。每个条目都有不同的Type键,每个项目列表都遵循该Type的约定。
3个回答

3

如果您愿意将所有内容静态存储,您可以使用类型系统:

static class MyDict {
    private static class Data<T> {
        public static readonly List<T> items = new List<T>();
    }
    public static List<T> Get<T>() { return Data<T>.items; }
    public static void Add<T>(T item) { Data<T>.items.Add(item); }
}

请注意,这将使删除键变得不可能(您无法卸载类型),但您可以使用Clear()方法清除它。

2
您可以使用以下静态类。
public static class GenericLists
{
    private static Dictionary<Type, object> MyDict = new Dictionary<Type, object>();
    public static void NewEntry<T>()
    {
        MyDict.Add(typeof(T), new List<T>());
    }

    public static List<T> GetEntry<T>()
    {
        return (List<T>)MyDict[typeof(T)];
    }

    public static void RemoveEntry<T>()
    {
        MyDict.Remove(typeof(T));
    }

}

或者你可以使用。
public class GenericLists<T>
{
    private Dictionary<Type, List<T>> MyDict = new Dictionary<Type, List<T>>();

    public void NewEntry()
    {
        MyDict.Add(typeof(T), new List<T>());
    }

    public List<T> GetEntry()
    {
        return MyDict[typeof(T)];
    }

    public void RemoveEntry()
    {
        MyDict.Remove(typeof(T));
    }
}

如果您真的想要初始化它,但我认为静态方式会更好。

当您将value添加为new List<T>()时,为什么value是一个对象 - I4V
如果数据是静态的,你可以不需要任何转换就能完成。请看我的回答。 - SLaks
现在有什么不同。你只是重复了问题。 - I4V
@SLaks 如果我将静态类泛型化,那将是另一个选项。 - Yuriy Faktorovich

1
您也可以将其作为基于实例的类来完成(见下文),但如果适用,我更喜欢像SLaks在“使用类型系统”帖子中所示的那样,在静态类中使用静态变量。
public class GenericTypeListDictionary
{
    private readonly Dictionary<Type, object> _dictionaryOfLists = new Dictionary<Type, object>();

    public List<T> NewEntry<T>()
    {
        var newList = new List<T>();
        _dictionaryOfLists.Add(typeof(T), newList);
        return newList;
    }

    public List<T> GetEntry<T>()
    {
        object value;

        if (_dictionaryOfLists.TryGetValue(typeof(T), out value))
        {
            return (List<T>)value;
        }

        return null;
    }

    public void RemoveEntry<T>()
    {
        _dictionaryOfLists.Remove(typeof(T));
    }
}

2
不要在“Type”对象上锁定。同时,在仅有一个方法上进行锁定是毫无意义的,而在值类型上进行锁定更加无意义。 - SLaks
我删除了lock命令。这是因为我正在进行完全不相关的讨论时它悄然而至。但是,我不明白在处理多线程应用程序时仅在一个方法中加锁是毫无意义的断言。 - Grax32
1
我的意思是当其他方法修改相同的结构时,只锁定一个方法。这就像在人行道上只建一半的门。 - SLaks
这意味着如果我锁定了 .Add,我也应该锁定 .Remove。谢谢,这很有道理。 - Grax32
1
而且 .Get. 你需要始终锁定相同的对象,因为你试图保护对字典的访问,而不是列表。(实际上,使用 ConcurrentDictionary 会更好) - SLaks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接