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!
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.
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);
How to define such a dictionary?
The ' |= ' symbol is the bitwise OR assignment operator.
In mathematics, the tilde often represents approximation, especially when used in duplicate, and is sometimes called the "equivalency sign." In regular expressions, the tilde is used as an operator in pattern matching, and in C programming, it is used as a bitwise operator representing a unary negation (i.e., "bitwise ...
C operators are one of the features in C which has symbols that can be used to perform mathematical, relational, bitwise, conditional, or logical manipulations. The C programming language has a lot of built-in operators to perform various tasks as per the need of the program.
Use System.ComponentModel.Design.ServiceContainer
that is already available in .Net framework.
ServiceContainer container = new ServiceContainer(); IList<int> integers = new List<int>(); IList<string> strings = new List<string>(); IList<double> doubles = new List<double>(); container.AddService(typeof(IEnumerable<int>), integers); container.AddService(typeof(IEnumerable<string>), strings); container.AddService(typeof(IEnumerable<double>), doubles);
You may not even need a dictionary to be able to do 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>(); }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With