Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 单例模式的正确使用_C#_.net_Singleton - Fatal编程技术网

C# 单例模式的正确使用

C# 单例模式的正确使用,c#,.net,singleton,C#,.net,Singleton,我有一个要求,即只创建一个BillLines实例,这当然非常适合单例模式 看一下,我不太明白我在哪里创建了我的“新”对象(即有用的对象,而不是一些抽象的单例对象) 你觉得这对吗 public sealed class ContextSingleton { private static readonly Lazy<ContextSingleton> Lazy = new Lazy<ContextSingleton>(() => new Cont

我有一个要求,即只创建一个
BillLines
实例,这当然非常适合单例模式

看一下,我不太明白我在哪里创建了我的“新”对象(即有用的对象,而不是一些抽象的单例对象)

你觉得这对吗

public sealed class ContextSingleton
{
    private static readonly Lazy<ContextSingleton> Lazy =
        new Lazy<ContextSingleton>(() => new ContextSingleton());

    public static ContextSingleton Instance { get { return Lazy.Value; } }

    private ContextSingleton()
    {
    }

    //Is this correct?  Where should I 'new' this?
    public readonly IBillLineEntities Context = new BillLines.BillLines();
}
更新


我无法访问
BillLines
的内部,但我需要确保它只存在一个实例。

我假设
BillLines
应该是您的
实例变量

应该是这样的:

var contextSingleton = ContextSingleton.Instance.Context;
public static class ContextSingleton
{
    private static readonly Lazy<BillLines> _instance =
        new Lazy<BillLines>(() => new BillLines());

    public static BillLines Instance { get { return _instance.Value; } }

    private ContextSingleton()
    {
    }
}
ContextSingleton.Instance
编辑


这个答案的目标是创建一个关于特定类的单例。如果其他人可以访问您的
BillLines
类,并且可以创建自己的实例,那么您可能应该重新考虑您正在尝试做什么。如果您确实控制了您的
BillLines
类的公开,那么您应该使它只在您公开的单例的内部实现中公开,这样其他人就不能创建他们认为合适的
新BillLines

像这样简单的事情

public class BillLines
{
    private BillLines()
    {
    }
    private static BillLines _billLines = null;

    public static BillLines Instance
    {
        get
        {
            if (_billLines == null)
                _billLines = new BillLines();
            return _billLines;
        }
    }
}

感谢@JonSkeet和@RobH的评论,我走上了依赖注入的道路。我选择了它,它完成了我预期的工作:

public class NinjectBindings : NinjectModule
{
    public override void Load()
    {
        Bind<IBillLineEntities>.To<BillLines.BillLines>().InSingletonScope();
    }
}
公共类NinjectBindings:NinjectModule
{
公共覆盖无效负载()
{
Bind.To().InSingletonScope();
}
}

你到底想成为什么样的单身汉?(你确定你必须使用这种模式吗?我倾向于避免,我自己…)如果你的广告牌第二次出现,世界会以某种方式结束吗?因为您只需要其中一个并不是单例的原因,就像只需要一个int并不意味着int应该是单例一样。如果你有一个单件产品,你将如何对你的产品进行单元测试?你搞错了。如果需要将
BillLines
作为单例,则需要将其构造函数
private
和实例设置为从该类返回。将
ContextSingleton
设为私有是没有用的。任何人都可以调用
new BillLines()
任意次数。@JonSkeet-我想
BillLines
成为单身汉@nvoigt-是,多个实例在意外事务升级方面导致问题。
BillLines
是命名空间还是类型?我担心新的BillLines.BillLines()
…-1顺便说一句,这不是一个单身汉。是什么阻止了客户端创建
广告行
自身的实例?为什么这不是一个单例?他不应该将
广告行
作为一个公共类公开给客户端,它应该是底层实现的内部类。@YuvalItzchakov这不是单例的意思。这意味着您只能创建一个实例。如果您的代码本身创建了
新的BillLines()
这如何使其成为单例?@YuvalItzchakov它不会阻止创建其他实例。Siriam应用了相当严格的singleton定义,其中类有一个私有构造函数,不可能创建其他实例。我更喜欢将单例看作一个更广泛的概念,您只需要一个实例。这个更广泛的定义还包括一些变体,其中IoC容器只创建一个实例,而类本身不强制执行该限制。这不是线程安全的。OP的代码使用了
Lazy
,它封装了单个实例的线程安全创建。使用它通常是最好的选择。