More Elegant Way to Make a Generic Lookup Type
I want to store things for lookup by a generic type.
Case: I have a storage class that I want to expose a Get<T>(string key) method, and internally is uses specialized storage lookup instances for each type.
Is the only way to do that today to use a Dictionary<System.Type, AbstractThing> and then cast my AbstractThing to MoreSpecific<T>?
10 Replies
one way is proto-actor way
https://github.com/asynkron/protoactor-dotnet/blob/dev/src/Proto.Actor/Utils/TypedDictionary.cs
GitHub
protoactor-dotnet/src/Proto.Actor/Utils/TypedDictionary.cs at dev ·...
Proto Actor - Ultra fast distributed actors for Go, C# and Java/Kotlin - asynkron/protoactor-dotnet
That is just assigning a surrogate integer ID for each type added?
yeah
That would save a few operations per lookup (the hash of the type), so that is cool.
It wouldn't save me having to cast the value results, but I'm guessing I'm stuck with that no matter what.
in one way or the other there will be sacrifices
@boiled goose
I'll probably just change
storageThing.Get<T>(key)
to
storageThing.Lookup<T>().Get(key)
Doesn't avoid the need for a type lookup (that TypedDictionary would be perfect), but I can avoid the casting and if the consumer holds onto a specific lookup reference, then they can avoid the type lookup for all future calls.
@boiled goose thanks for the link
The lookup type implements a non allocating StartsWith search, and right now to get around the issues of this help post I'm using LINQ to cast the IEnumerable (which boxes the struct enumerator, killing the performance benefit of making the enumerator non-allocating).
These changes will look great on my benchmarks 😆If you are in a DI context, you could just register lookups for each T and use an inner scope service provider
Though at that point you pretty much reinvented named services that we got recently, can prolly just use that
That would be a good idea, and is similar to how I plan to consume these types in my own projects.
The types though, are in an open source library and I want the library to remain neutral about configuration and dependency choices of the consumer. I won't pressume they are using a specific (or any) DI container.
In that case I would just define a lookup interface, and make a few implementation options in sub packages for the consumer to choose how it's backed