继承类上的 C# 单例模式

标签 c# design-patterns inheritance singleton

我将以对帖子的长度表示歉意来开始这个问题。为了节省你一些时间,我的问题是我脑子里的类模式显然有缺陷,我看不到好的解决方案。

在我正在进行的项目中,我需要对一大块数据使用运算算法,我们称它们为DataCache。有时这些算法返回的结果本身需要缓存,所以我设计了一个方案。

我有一个看起来像这样的算法基类

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;
        }
}

如果您调用 ComputeResult() 并提供一个 DataCache,您可以选择缓存结果。另外,如果你幸运的话,如果 GC 还没有收集到结果,结果可能仍然存在。每个 DataCache 的大小以数百兆字节为单位,在您询问之前,每个 DataCache 中大约有 10 个数组,其中包含基本类型,例如 intfloat

我的想法是,实际的算法应该是这样的:

class ActualAgorithm : Algorithm<SomeType>
{
    protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache)
    {
       //Elves be here
    }
}

我会定义数十个 .cs 文件,每个文件对应一种算法。这种方法有两个问题。首先,为了让它工作,我需要实例化我的算法并保留该实例(或者不缓存结果并且整个点都静音)。但是后来我在每个派生类中都得到了一个难看的单例模式实现。它看起来像这样:

class ActualAgorithm : Algorithm<SomeType>
{
    protected override SomeType ExecuteAlgorithmLogic(DataCache dataCache)
    {
       //Elves and dragons be here
    }
    protected ActualAgorithm(){ }
    private static ActualAgorithm _instance;
    public static ActualAgorithm Instance
    {
        get
        {
            _instance = _instance ?? new ActualAgorithm();
            return _instance;
        }
    }
}

因此,在每个实现中,我都必须为单例模式复制代码。其次,数十个 CS 文件听起来也有点矫枉过正,因为我真正想要的只是一个函数返回一些可以为各种 DataCache 对象缓存的结果。当然,必须有一种更聪明的方法来做到这一点,我将不胜感激朝着正确方向的插入。

最佳答案

我的评论的意思是这样的:

abstract class BaseClass<K,T> where T : BaseClass<K,T>, new()
{
    private static T _instance;
    public static T Instance
    {
        get
        {
            _instance = _instance ?? new T();
            return _instance;
        }
    }
}

class ActualClass : BaseClass<int, ActualClass>
{
    public ActualClass() {}
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(ActualClass.Instance.GetType().ToString());
        Console.ReadLine();
    }
}

这里唯一的问题是您将拥有一个公共(public)构造函数。

关于继承类上的 C# 单例模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4470424/

相关文章:

wpf - 如何操作TreeView中的数据?我应该使用 ViewModelPattern 吗?

C++:在继承链中放置构造函数的位置?

java - 如何使用JPA制作Maven包,但独立于服务提供商;稍后如何由该包的用户插入我的服务提供商?

python-3.x - 在父类(super class)中缓存属性

c++ - 混淆理解虚函数调用和依赖基类

c# - 在 IIS Windows 7 中无法访问此站点

c# - 重复 ViewComponent 数据

c# - 如何判断 ParameterInfo 类型是否为集合?

c# - PrincipalSearcher 和 DirectorySearcher 之间的区别

java - 调整复合(设计模式)形状的大小