Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.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#_Static_Constructor_Singleton - Fatal编程技术网

C#-单态模式

C#-单态模式,c#,static,constructor,singleton,C#,Static,Constructor,Singleton,正如你们从我的昵称中所看到的,我是一个新手,实际上在学习单例模式,我遇到了一个问题。在我了解静态构造函数总是在标准构造函数之前执行之前,但是在下面的代码中,结果是不同的,首先我看到“Insta”字符串,然后是“static”,为什么会发生这种情况 sealed class Singleton { private static readonly Singleton instance; private Singleton() { Console.WriteL

正如你们从我的昵称中所看到的,我是一个新手,实际上在学习单例模式,我遇到了一个问题。在我了解静态构造函数总是在标准构造函数之前执行之前,但是在下面的代码中,结果是不同的,首先我看到“Insta”字符串,然后是“static”,为什么会发生这种情况

sealed class Singleton
{
    private static readonly Singleton instance;

    private Singleton()
    {
        Console.WriteLine("Insta");
    }

    static Singleton()
    {
        instance  = new Singleton();
        Console.WriteLine("Static");
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

class Program
{
    static void Main()
    {
        Singleton s1 = Singleton.Instance;

    }

}
如果你愿意写

static Singleton()
{
    Console.WriteLine("Static"); //THIS COMES FIRST
    instance  = new Singleton();

}
你会看到你所期待的

正如预期的那样,静态ctor首先被执行,但您在控制台上打印
instance=newsingleton()行,但这行执行实例ctor,所以“inst”

因此,执行流程:

  • 静态定向器
    • instance=newsingleton()
      
      • 实例ctor打印“insta”
    • “静态”
有关单例模式的质量说明,请参阅

MSDN建议您按照以下方式编写,以确保线程安全:

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}
 
顺便说一下,与静态构造函数相比,此模式具有以下优势:

在对象请求实例之前,不会执行实例化;这种方法称为延迟实例化。延迟实例化避免在应用程序启动时实例化不必要的单例


查看这是否满足您的需要,如果满足,请实施此解决方案。

首先调用静态方法。这是证据--将代码更改为以下内容:

static Singleton()
    {
        Console.WriteLine("Static method start");
        instance  = new Singleton();
        Console.WriteLine("Static method end");
    }

相关:不确定您期望的推理——“先调用静态构造函数”并不意味着“在所有调用类成员之前神奇地执行静态构造函数中的所有代码”(在您的情况下是实例构造函数)。纠正我的错误,谢谢。但我还有一个问题要问你,如果我写“private static readonly Singleton instance=new Singleton();”编译器会把这个表达式移到static ctor还是什么?@csharp初学者不,这个Singleton实例将在第一次调用这个类时构造,你不再需要静态构造函数了,那么这个初始化工作原理与静态构造函数相同吗?@CSharp初学者:如果说“相同的方式”,你的意思是只初始化一次,是的。线程安全与这样一个概念性问题有什么关系?我的重点是介绍MSDN文章,介绍如何实现单例解决方案。不需要重新发明轮子。因为他是一个初学者,所以有一篇好的文章来阅读和理解特定的模式总是很好的。