gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 12:45:18 25 4
gpt4 key购买 nike

我目前有 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 ’。”

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

最佳答案

or have I gone in the wrong direction?

看起来像这样。

首先,_lazy字段的类型为 Lazy<SingletonBase<T>> .因此,您不能通过 T实例到它的构造函数中。

这里唯一的选择是传递一个委托(delegate),它返回 SingletonBase<T> 的实例-派生类型(因为 SingletonBase<T> 是抽象的)。显然,您需要一种方法来获取此实例。现在请注意,这是抽象类中的 static 属性 getter 的代码。

你打算如何做到这一点?
您不能覆盖静态方法或属性。

第二个,单例的利润是多少,它包装了Lazy<T> ?为什么不创建线程安全的 Lazy<T> :

var singleton = new Lazy<YourClass>(true);

或:

var singleton = new Lazy<YourClass>(SomeMethodThatCreatesYourClass, true);

UPD

根据您对问题的修改,您正在尝试混合两种职责:

  • 单例对象的创建;
  • 创建T来自数据库的对象。

这不是一条出路。您需要一个基 工厂 类(或者甚至一个接口(interface),如果没有任何逻辑,可以在基类中实现):

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

然后,你需要创建一些后代,例如:

class Factory1 : Factory<YouClass1> {}
class Factory2 : Factory<YouClass2> {}
// etc

然后,如果你想让它们成为单例,你只需要将特定的工厂包装到 Lazy<T> 中。实例,例如:

static class Singletons
{
private static readonly Lazy<Factory1> factory1;
private static readonly Lazy<Factory2> factory2;

static Singletons()
{
factory1 = new Lazy<Factory1>(true); // or Lazy<Factory1>(() => /* */, true)
factory2 = new Lazy<Factory2>(true); // or Lazy<Factory2>(() => /* */, true)
}

public Factory1 Factory1
{
get { return factory1.Value; }
}
public Factory2 Factory2
{
get { return factory2.Value; }
}
// etc
}

并以这种方式使用它们:

Singletons.Factory1.For("ab-CD")
Singletons.Factory2.For("ef-GH")

Lazy<T>本身具有惰性初始化的单例实现。使用第二个 bool 参数 true它是一个线程安全的实现。因此,您不需要包装它,不需要编写所有这些锁和双重检查代码。

关于c# - 单例的通用抽象基类 (C#) - 无法实例化私有(private) Lazy 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25180064/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com