在C#中:如何声明一个类型为通用的通用字典和一个IEnumerable&那种价值? [英] In C#: How to declare a generic Dictionary with a type as key and an IEnumerable<> of that type as value?
问题描述
我想声明一个字典,存储一个特定类型的键入的 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屋!