有这样一个类:    class myTest {
        private static myTest mt;        static myTest() {
            mt = new myTest();
        }
    }请问,myTest是怎么样在自己内部,用myTest自己定义字段的和对象实例化的?原理是怎么样的?
也许是很简单的问题,可是我没有搞懂这个究竟是这么一个形式。请大家帮忙解答一下,谢谢。

解决方案 »

  1.   

    因为mt这个成员是静态的,只会保存一份,所以这段代码应该没有什么问题。
    但如果把static去掉就会有问题,不知道编译器会不会让它通过,就算通过了,实例化的时候也会有堆栈溢出的异常吧。
      

  2.   

    简单的单件模式(内存中只保留一份myTest)
    希望下面这段代码能帮你理解它的含义
    using System;
    using System.IO;
    using System.Collections;public class MyClass
    {
    public static void Main()
    {
    //First
    Singleton t1 = Singleton.Instance;
    Singleton t2 = Singleton.Instance;
    t1.t = "test";
    Console.WriteLine(Object.ReferenceEquals(t1,t2)==true);
    Console.WriteLine(t2.t);
    Console.ReadLine();

    //Second
    Singleton2 t3 = Singleton2.Instance;
    Singleton2 t4 = Singleton2.Instance;
    t3.t = "test";
    Console.WriteLine(Object.ReferenceEquals(t3,t4)==true);
    Console.WriteLine(t4.t);
    Console.ReadLine();
            
            //Third
    Singleton3 t5 = Singleton3.Instance;
    Singleton3 t6 = Singleton3.Instance;
    t5.t = "test";
    Console.WriteLine(Object.ReferenceEquals(t3,t4)==true);
    Console.WriteLine(t6.t);
    Console.ReadLine();
            
            Console.WriteLine(Singleton3.Instance);
            Console.ReadLine();
            
            //Forth
            Singleton4 t7 = Singleton4.GetInstance(100,200);
            Singleton4 t8 = Singleton4.GetInstance(200,300);
            Console.WriteLine(Object.ReferenceEquals(t7,t7)==true);
            Console.WriteLine(t7.x + "--" + t7.y);
            Console.WriteLine(t8.x + "--" + t8.y);
            Console.ReadLine();
    }
    }//Normal Singleton
    class Singleton
    {
    private static Singleton instance;

    private Singleton(){}

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

    private string m_t;
    public string t 
    {
    get{ return m_t; }
    set{ m_t = value; }
    }
    }//Multi-thread Singleton
    class Singleton2
    {
        //限定一个对象可被外部进程(操作系统、硬件或并发线程等)改变
    private static volatile Singleton2 instance = null;

    private static object lockHelper = new Object();

    private Singleton2() {}

    public static Singleton2 Instance
    {
    get
    {
    if(instance == null)
    {
    lock (lockHelper)
    {
    if(instance == null)
    {
    instance = new Singleton2();
    }
    }
    }
    return instance;
    }
    }

    private string m_t;
    public string t 
    {
    get{ return m_t; }
    set{ m_t = value; }
    }
    }//Static Singleton
    class Singleton3
    {
        //Create a readonly instance
        public static readonly Singleton3 Instance;
        static Singleton3()
        {
            Instance = new Singleton3();
        }
        
        private Singleton3() { }
        
    private string m_t;
    public string t 
    {
    get{ return m_t; }
    set{ m_t = value; }
    }    
    }//Normal Singleton
    class Singleton4
    {
    private static Singleton4 instance;

        public int x;
        public int y;
    private Singleton4(int x,int y)
        {
            this.x = x;
            this.y = y;
        }

    public static Singleton4 GetInstance(int x,int y)
    {
    if(instance == null)
    {
    instance = new Singleton4(x,y);
    }
            else    //Overwrite the property,but just one object
            {
                instance.x = x;
                instance.y = y;
            }
    return instance;
    }
    }
      

  3.   

    在Snippet Compiler中单步执行它就可以
      

  4.   

    谢谢各位的解答,不过都不是我要问的原意。看来是我没有表达好意思,我说的是一个类怎么在内部使用自己来定义字段和方法的原理,不一定是静态的类。比如有一个类A,在其内部有个字段定义为A a = new A();那么请问这是怎么样一个原理和运行机制?
      

  5.   

    先编译,类的结构,有哪些字段,都是什么类型的,有哪些方法这些内容都会由你的源代码的表达(一个长字符串)变成结构化的表达,存放在assembly里面,同时类中的方法也会被编译成IL,注意在这个过程中,你的初始化代码,构造函数之类的并没有执行,所以类中引用自己是没有问题的,不会引起递归之类的问题,引用自己类型的那个成员,编译器不会特殊对待他,和引用别的类型是没有区别的,它只知道这里有个成员他是A类型的引用,它只要知道A类型存在就可以了。也许你会问,这时A类型还不存在呢?这是个好问题,说实话我并不知道C#编译器是如何工作的,我猜想它会维护一张Tpye表,当它读到类似Class A的内容的时候就会在这张表中增加内容。
      

  6.   

    谢谢copine的解答还有其他高手要补充一下吗?我想把这个问题彻底搞清楚,呵呵,总是有疑问压在心里不舒服。