我们如何创建Singleton Instance的克隆对象?

时间:2016-10-07 06:44:21

标签: c# singleton

我的代码中有一个单例类 在我的主要功能中,我创建了该类的一个对象 然后,我尝试为该对象创建克隆 而且,它给了我“StackOverflowException”。

我的代码如下:

namespace SingletonApplication
{
    class A : ICloneable
    {
        private static readonly A A1 = new A();

        public A A2 { get { return A1; } }
        public object Clone()
        {
            var obj = ((ICloneable)A1).Clone();
            return obj;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            A obj1 = new A();
            A obj2 = (A)(obj1.Clone());

            Console.WriteLine(object.ReferenceEquals(obj1.A2, obj2.A2));

            Console.ReadKey();
        }

    }
}

错误: enter image description here

4 个答案:

答案 0 :(得分:2)

根据定义,Singleton是一个在整个应用程序中只有一个实例的类。

你得到的StackOverflowException是由Clone menthod造成的,它一直在调用自己。

答案 1 :(得分:1)

这些要求是矛盾的:

  • Singleton最多可以通过自己的定义一个一个
  • Clone()方法应该生成 clone ,一个新的(== 第二个)实例

可能更好的解决方案是返回克隆(即自身)

   // sealed: do not inherit from me (I'm a Singleton) and create a second instance
   sealed class A : ICloneable
   {
       private static readonly A A1 = new A();

       //private constructor: do not create instances (I'm a Sinleton)
       private A() {}

       public A A2 { get { return A1; } }

       // We can't create a new clone but can return an existing instance
       public object Clone()
       {
           // Cloned Singleton? Let it be itself
           return this;
       }
   }

答案 2 :(得分:0)

不是一遍又一遍地在同一个对象上递归调用Clone,而是应该做一些事情来克隆该对象。

通常您创建一个新实例并复制所有相关属性。像这样:

A newA = new A();
newA.X = this.X;

return newA;

但是,您的代码中没有任何内容可以复制。 readonly字段将保持不变。我想知道为什么你需要一个单身的副本,因为这会破坏设计模式的目的。顺便说一下,你实现单例是非常独特的。我建议阅读单身人士并在那里跟踪一些样本。

答案 3 :(得分:0)

导致错误的原因是您让Clone调用自身。导致无限循环 这不是单身人士。单身人员应该看起来像这样

class A 
    {
        private static A instance;

        private A() { }

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