在C#中:如何声明一个类型为通用的通用字典和一个IEnumerable&那种价值? [英] In C#: How to declare a generic Dictionary with a type as key and an IEnumerable<> of that type as value?

查看:208
本文介绍了在C#中:如何声明一个类型为通用的通用字典和一个IEnumerable&那种价值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想声明一个字典,存储一个特定类型的键入的 IEnumerable ,其确切类型如下:(编辑为遵循johny g的注释)

I want to declare a dictionary that stores typed IEnumerable's of a specific type, with that exact type as key, like so: (Edited to follow johny g's comment)

private IDictionary<Type, IEnumerable<T>> _dataOfType where T: BaseClass; //does not compile!

我想要存储的具体类,都来自BaseClass,因此将其用作约束。编译器抱怨说,它希望在成员名后面加上一个分号。

The concrete classes I want to store, all derive from BaseClass, therefore the idea to use it as constraint. The compiler complains that it expects a semicolon after the member name.

如果这样工作,我希望这将使得从字典中稍后检索简单如下: p>

If it would work, I would expect this would make the later retrieval from the dictionary simple like:

IEnumerable<ConcreteData> concreteData;
_sitesOfType.TryGetValue(typeof(ConcreteType), out concreteData);

如何定义这样的字典?

推荐答案

你可能甚至不需要一本字典来解决这个问题 - 但这取决于你的需要。如果您每个应用程序只需要一个这样的列表(即字典是 static ),则以下模式可以很有效,并且可以很好地促进类型推断: p>

You may not even need a dictionary to be able to due this - but that depends on your needs. If you only ever need 1 such list per type per appdomain (i.e. the "dictionary" is static), the following pattern can be efficient and promotes type-inference nicely:

interface IBase {}

static class Container {
    static class PerType<T> where T : IBase {
        public static IEnumerable<T> list;
    }

    public static IEnumerable<T> Get<T>() where T : IBase 
        => PerType<T>.list; 

    public static void Set<T>(IEnumerable<T> newlist) where T : IBase 
        => PerType<T>.list = newlist;

    public static IEnumerable<T> GetByExample<T>(T ignoredExample) where T : IBase 
        => Get<T>(); 
}

请注意,在采用这种方法之前,时间类型和运行时类型。这个方法很乐意让您在 SomeType 之间存储运行时类型的 IEnumerable< SomeType> 变量,它包含 SomeType 的基本类型,包括 IBase ,既没有运行时也没有编译类型错误 - 这可能作为一个功能,或者一个等待发生的错误,所以你可能需要一个,如果来检查。

Note that you should think carefully before adopting this approach about the distinction between compile-time type and run-time type. This method will happily let you store a runtime-typed IEnumerable<SomeType> variable both under SomeType and -if you cast it- under any of SomeType's base types, including IBase, with neither a runtime nor compiletype error - which might be a feature, or a bug waiting to happen, so you may want an if to check that.

另外,这种方法忽略了线程;所以如果你想从多个线程访问这个数据结构,你可能需要添加一些锁定。参考读/写是原子的,所以如果你不能锁定你不会得到腐败,但是陈旧的数据和竞争条件肯定是可能的。

Additionally, this approach ignores threading; so if you want to access this data-structure from multiple threads, you probably want to add some locking. Reference read/writes are atomic, so you're not going to get corruption if you fail to lock, but stale data and race conditions are certainly possible.

这篇关于在C#中:如何声明一个类型为通用的通用字典和一个IEnumerable&那种价值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆