加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

单例的通用抽象基类(C#) – 无法实例化私有Lazy实例

发布时间:2020-12-15 22:06:57 所属栏目:百科 来源:网络整理
导读:我目前有一个6或7个单例的集合,所有这些单体几乎完全相同(参见下面示例中的For方法)但是使用不同的内部数据库查询并返回不同对象的集合(因此解析数据库结果是每个单身人士都不同). 因此,使用this question作为我的基础,我一直在尝试在C#中为这些单例构建一个
我目前有一个6或7个单例的集合,所有这些单体几乎完全相同(参见下面示例中的For方法)但是使用不同的内部数据库查询并返回不同对象的集合(因此解析数据库结果是每个单身人士都不同).

因此,使用this question作为我的基础,我一直在尝试在C#中为这些单例构建一个抽象的通用基类.

在SO上有similar questions但没有实现Lazy,我希望如此.

到目前为止,我有这个

public abstract class SingletonBase<T> where T : class,new()
{
    private static Lazy<SingletonBase<T>> _lazy;
    private static readonly object _lock = new object();

    public static SingletonBase<T> Instance
    {
        get
        {
            if (_lazy != null && _lazy.IsValueCreated)
            {
                return _lazy.Value;
            }

            lock (_lock)
            {
                if (_lazy != null && _lazy.IsValueCreated)
                {
                    return _lazy.Value;
                }

                *****  this is the problem line  *****
                _lazy = new Lazy<SingletonBase<T>>(new T());
            }

            return _lazy.Value;
        }
    }

    public abstract IEnumerable<T> For(string systemLangCode);
}

但是,线路上出现问题

_lazy = new Lazy<SingletonBase<T>>(new T());

Visual Studio告诉我“无法解析构造函数’Lazy< T>‘.”

我不确定应该将什么传递给Lazy< SingletonBase< T>>的构造函数,还是我走错了方向?

解决方法

尽管有一些很好的建议,但我仍然想使用单例来提供解决方案,因为我觉得我可以用更简单的代码来实现这一点.这就是我所做的.

这是通用基类.

public abstract class SingletonBase<S,T> where S : class,new()
{
    protected static readonly Dictionary<string,List<T>> Dictionary = new Dictionary<string,List<T>>();
    private static readonly S _instance = new S();
    private static readonly object _lock = new object();

    public static S Instance
    {
        get
        {
            lock (_lock)
            {
                return _instance;
            }
        }
    }

    public IEnumerable<T> For(string systemLangCode)
    {
        systemLangCode = systemLangCode.ToLower();

        if (!Dictionary.ContainsKey(systemLangCode))
        {
            PopulateDictionary(systemLangCode);
        }

        return Dictionary.FirstOrDefault(d => d.Key == systemLangCode).Value;
    }

    protected abstract void PopulateDictionary(string systemLangCode);
}

我实际上在这里做的是,除了实例化和缓存派生类型的实例S之外,还处理对T的集合的请求,而不是查询数据库,并存储所有可能的记录集,我查询记录集在需要时,使用systemLangCode作为查询中的变量,将此记录集解析为List< T>,然后使用systemLangCode作为键将此集合存储在Dictionary中.

因此,仅在先前未通过该单例获取此结果集时才进行查询.

这是上述基类的推导.

public sealed class Languages : SingletonBase<Languages,Language>
{
    protected override void PopulateDictionary(string systemLangCode)
    {
        var languages = new List<Language>();

        // some DB stuff

        Dictionary.Add(systemLangCode,languages);
    }
}

这个基类现在允许我构建一系列派生类,它们只包含数据库查询.因此,我现在有一个单身人士的单一定义,我可以用它来存储,例如,不同语言的语言集合,不同语言的国家集合,不同语言的时区集合等.

用法示例:

var langsDe = Languages.Instance.For("de");
var langsEn = Languages.Instance.For("en");

如果我以后打电话

var langsDe = Languages.Instance.For("de");

然后,这将从内部词典中检索.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读