日期:2014-05-18  浏览次数:20906 次

Singleton 单例模式无法嵌套使用?
因为整个工程要求各模块及参数类全局通用,因此考虑单例设计
定义了如下几个类

C# code

    public sealed class MachineParameters
    {
        // Singleton
        public static readonly MachineParameters instance = new MachineParameters();
        public static MachineParameters GetInstance()
        {
            return instance;
        }

        // 为了实现类似单例的全局调用效果,因此想到
        public Machine M1 = new Machine(1);
        public Machine M2 = new Machine(2);
        public Machine M3 = new Machine(3);
        public Machine M4 = new Machine(4);

        // 为了便于轮询,将所有 Machine 类实例放入数组
        public Machine[] M = new Machine[4];

        private MachineParameters()
        {
            M[1] = M1;
            M[2] = M2;
            M[3] = M3;
            M[4] = M4;
        }
    }

    public sealed class TimingController
    {
        // Singleton
        private static readonly TimingController instance = new TimingController();
        public static TimingController GetInstance()
        {
            return instance;
        }

        MachineParameters Machines = MachineParameters.GetInstance();

        // 方便的全局式调用如下
        Machines.M[i].Speed = 100;
    }

    public class Machine //实例类
    {
**(1)        TimingController Timing = TimingController.GetInstance();
        UpdateData Update = UpdateData.GetInstance();
        //省略其余定义
        //类中用到了 TimingController 和 UpdateData ,因此声明如上
        public Machine(int id)
        {
**(2)            Timing.WarmedUp += new TimingEventHandler(Update.UpdateMachine);
        }
    }


    public partial class MainWindow : Form
    {
        // Singleton
        //public static readonly MainWindow instance = new MainWindow();
        //public static MainWindow GetInstance()
        //{
        //    return instance;
        //}

        // 主窗体类,程序从这里开始
***(3)        TimingController Timing = TimingController.GetInstance();
    }




代码大体是这样,但是当我 F5 运行的时候,错误提示 “The type initializer for 'TimingController' threw an exception.”,
详细错误信息为:InnerException: System.NullReferenceException
  Message=Object reference not set to an instance of an object.
错误行定位在 **(3) 处

但是当我把 **(1) 和 **(2) 删掉,错误就消失了,看起来像是某种循环嵌套的样子

但是我总不能不用 **(1) 和 **(2) 的语句吧,所以请问有什么好的解决方案么?


另外:被我注释掉的 MainWindow 的单例代码,如果启用,会在 **(4) 处出现类似的错误提示
C# code

static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
**(4)            Application.Run(new MainWindow());
        }
    }
    


可是如果不把窗体也全局单例的话,又如何在其他类修改窗体上的 label,textbox 之类的呢?把 MainWindow 的实例作为参数传递给修改 UI 的类?这个类还是多线程的,要 invoke 比较麻烦哪

------解决方案--------------------
你的singleton模式本身就用的不对。
------解决方案--------------------
单实例一般应用于某个全局分配或某种资源管理或缓存,其他建议少用.
------解决方案--------------------
没仔细看这么多代码,头疼,但是何必要转这么多弯来实现单例呢?如果只是为了学习,那另当别论。但是实际上,最简单的单例:
public static SingletonClass...加一个static即可。

如果上升到框架,MEF可以很简单的帮你实现单例,有兴趣可以去学一下。
------解决方案--------------------
目测几个问题。你那个数组容量就是4,你后续为它赋值的时候用的下标是1 2 3 4,不会出错吗?另外一个就是你的成员变量不是在构造函数里面初始化的,这个有可能造成空引用的错误。