I will start this question by apologizing for the length of the post. So that I save you a little, the problem is that the class that I stuck in my head is clearly corrupted, and I do not see a good solution.
In the project I'm working on, I need to use algorithms for working on pieces of data, call them DataCache . Sometimes these algorithms return results that must themselves be cached, and so I developed a scheme.
I have an Algorithm base class that looks like this
abstract class Algorithm<T> { protected abstract T ExecuteAlgorithmLogic(DataCache dataCache); private readonly Dictionary<DataCache, WeakReference> _resultsWeak = new Dictionary<DataCache, WeakReference>(); private readonly Dictionary<DataCache, T> _resultsStrong = new Dictionary<DataCache, T>(); public T ComputeResult(DataCache dataCache, bool save = false) { if (_resultsStrong.ContainsKey(dataCache)) return _resultsStrong[dataCache]; if (_resultsWeak.ContainsKey(dataCache)) { var temp = _resultsWeak[dataCache].Target; if (temp != null) return (T) temp; } var result = ExecuteAlgorithmLogic(dataCache); _resultsWeak[dataCache] = new WeakReference(result, true); if (save) _resultsStrong[dataCache] = result; return result; } }
If you call ComputeResult() and provide a DataCache , you can choose to cache the result. Also, if you're lucky, it could still be if the GC hasn't assembled it yet. The size of each DataCache is hundreds of megabytes, and before you ask, each of them has about 10 arrays that contain basic types such as int and float .
My idea here was that the actual algorithm would look something like this:
class ActualAgorithm : Algorithm<SomeType> { protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache) {
And I would define dozens of .cs files, each for one algorithm. There are two problems with this approach. Firstly, in order for this to work, I need to create an instance of my algorithms and save this instance (or the results are not cached, and the whole point is inactive). But then I get an unsightly implementation of a singleton pattern in every derived class. It will look something like this:
class ActualAgorithm : Algorithm<SomeType> { protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache) {
Therefore, in each implementation, I would have to duplicate the code for a singleton template. And secondly, dozens of CS files also seem a little redundant, because what I'm actually after is just one function that returns some results that can be cached for various DataCache objects. Of course, there should be a more reasonable way to do this, and I would be very grateful for pushing in the right direction.