有的时候我们会碰到这样的情况:在一个窗体中,我们点击一个按钮产生一个新的窗体,如果我们在代码中不进行限制的话,再点击一次按钮,又会产生一个窗体,对于每个窗体当然是有一个窗体的实例和它对应,如果我想在程序中只允许生成一个类的实例该怎么办呢?其实实现上面不能再产生一个新的窗体还是比较简单的实现的,可以在产生了窗体以后我们设置按钮属性为不可用:Button1.Enable=false; 

但是,我在这里想实现的是不用让按钮不可用,来完成程序只能产生一个类的实例的方法: 

方法一: 

如果一个类你只想一个实例对其进行操作,那么我们可以将类中的域,属性以及函数都定义为static的,而且我们把构造函数定义成private的,这样只有类名才能对类里面的域,属性还有方法进行访问了,而且该类也不能在类外创建一个实例了。 

public class Class2  
 { 
            private Class2(){}  
            public static Type VariableName;  
            public static Type FunctionName(){}  
 }

这中方法不适合于WINFORM程序中的窗体类。 

方法二:  
设置一个bool型的变量来表识是否已经创建了一个实例。 

public class Class2 
     { 
         private Class2() 
         { 
         } 
         private static bool instance_flag=false; 
         public static Class2 GetInstance() 
         { 
             if(!instance_flag) 
             { 
                 Class2 c2=new Class2(); 
                 instance_flag=true; 
                 return c2; 
             } 
             else 
             { 
                 Console.WriteLine("you have already create a instance"); 
                 return null; 
             } 
  
         } 
     }


 

如果已经创建了一个实例,那么instance_flag=true,这样程序就知道已经有一个实例已经创建,将不会创建新的实例。 

方法三: 

在Class2中创建一个类的实例,该实例是static的,然后在类外面直接用这个实例进行赋值,也可通过函数来返回这个类的实例。但是这样的话,就会在编译的时候就会产生这个类的实例,它会浪费资源,效率也不高,可以在需要用到实例的时候才生成,代码如下: 

public class Class2 
     { 
         private Class2() 
         { 
         } 
         private static Class2 c2=null; 
         public static Class2 GetInstance() 
         { 
             if(c2==null) 
             { 
                 c2=new Class2(); 
             } 
             return c2; 
         } 
     }


 

static方法只能访问static的域。根据以上代码,在需要使用实例的时候,可以用类名来调用GetInstance()方法。来返回一个实例。 

以上方法不能使用构造函数,因为都将构造函数设置成了private的,目的也是这样,禁止多次生成实例。新手感想,有问题请帮忙指出,谢谢! 

评论: 
# re: C#中只允许产生一个类的实例的方法 2005-04-24 03:17 | 一滴水

一下是我在《C#设计模式》 看到的 单件模式 

你那样的话有一个问题就是你在每次 实例话得时候要判断是否null 

在单件模式里这样处理的 
创建一个新类,如果用户试图多次实例化此类,会抛出异常; 

class MyException:Exception 
 { 
 public MyException(string s) 
 : base(s) 
 { 
 } 
 } 
 接下来修改一下你的class2 
 public class Class2 
 { 
 public Class2() 
 { 
 if (instance_flag) 
 { 
 throw new MyException("you have already create a instance"); 
 } 
 else 
 { 
 instance_flag = true; 
 } 
 } 
 private static bool instance_flag = false; 
 }


这样就不用出来是在判断 了