看下面代码:  
在构造器中,代码先后使用了btn变量来创建按钮,它这么做难道不会丢失对btn的句柄吗?  
书中的解释是:同时,因为我对两个按钮使用了两个不同的Click事件处理程序,所以也不需要将按钮对象作为字段存储。我使用同一个btn变量创建两个按钮。  
 
using  System;  
using  System.Drawing;  
using  System.Windows.Forms;  
 
class  TwoButtonsDock:  Form  
{  
         
         public  static  void  Main()  
         {  
                   Application.Run(new  TwoButtonsDock());  
         }  
         public  TwoButtonsDock()  
         {  
                   Text  =  "Two  Buttons  with  Dock";  
                   ResizeRedraw  =  true;  
 
                   Button  btn  =  new  Button();  
                   btn.Parent  =  this;  
                   btn.Text      =  "&Larger";  
                   btn.Height  =  2  *  Font.Height;  
                   btn.Dock      =  DockStyle.Fill;  
                   btn.Click  +=  new  EventHandler(ButtonLargerOnClick);  
                     
                   btn  =  new  Button();  
                   btn.Parent  =  this;  
                   btn.Text      =  "&Smaller";  
                   btn.Height  =  2  *  Font.Height;  
                   btn.Dock      =  DockStyle.Bottom;  
                   btn.Click  +=  new  EventHandler(ButtonSmallerOnClick);  
         }  
         void  ButtonLargerOnClick(object  obj,  EventArgs  ea)  
         {  
 
                 Left  -=  (int)(0.05  *  Width);  
                 Top  -=  (int)(0.05  *  Height);  
                 Width  +=  (int)(0.10  *  Width);  
                 Height  +=  (int)(0.10  *  Height);  
         }  
         void  ButtonSmallerOnClick(object  obj,  EventArgs  ea)  
         {  
 
                 Left  +=  (int)(Width  /  22f);  
                 Top  +=  (int)(Height  /  22f);  
                 Width  -=  (int)(Width  /  11f);  
                 Height  -=  (int)(Height  /  11f);  
         }  
}  
 
 
 
在看看另一段代码:  
看这段代码构造器里的for循环中,它也用同样的chkbox变量来创建CheckBox控件的对象,但它使用了同样的CheckedChanged事件,这又是怎么回事??  
 
using  System;  
using  System.Drawing;  
using  System.Windows.Forms;  
 
class  CheckBoxWithLabel:  Form  
{  
         Label  label;  
 
         public  static  void  Main()  
         {  
                   Application.Run(new  CheckBoxWithLabel());  
         }  
         public  CheckBoxWithLabel()  
         {  
                   Text  =  "CheckBox  Demo  with  Label";  
 
                   int            cyText      =  Font.Height;  
                   int            cxText      =  cyText  /  2;  
                   string[]  astrText  =  {"Bold",  "Italic",  "Underline",  "Strikeout"};  
 
                   label  =  new  Label();  
                   label.Parent      =  this;  
                   label.Text          =  Text  +  ":  Sample  Text";  
                   label.AutoSize  =  true;  
 
                   for  (int  i  =  0;  i  <  4;  i++)  
                   {  
                             CheckBox  chkbox  =  new  CheckBox();  
                             chkbox.Parent  =  this;  
                             chkbox.Text  =  astrText[i];  
                             chkbox.Location  =  new  Point(2  *  cxText,    
                                                                                             (4  +  3  *  i)  *  cyText  /  2);  
                             chkbox.Size  =  new  Size(12  *  cxText,  cyText);  
                             chkbox.CheckedChanged  +=    
                                                           new  EventHandler(CheckBoxOnCheckedChanged);  
                   }  
         }  
         void  CheckBoxOnCheckedChanged(object  obj,  EventArgs  ea)  
         {  
                   FontStyle      fs      =  0;  
                   FontStyle[]  afs    =  {  FontStyle.Bold,            FontStyle.Italic,    
                                                             FontStyle.Underline,  FontStyle.Strikeout  };  
 
                   for  (int  i  =  0;  i  <  4;  i++)  
                             if  (((CheckBox)  Controls[i  +  1]).Checked)  
                                       fs    &brvbar;=  afs[i];  
 
                   label.Font  =  new  Font(label.Font,  fs);  
         }  
}  

解决方案 »

  1.   

    //看见这样的语句搂主是不是更晕了?没有变量就创建了一个按钮private void Form1_Load(object sender, EventArgs e)
    {
        new Button().Parent = this;
    }变量是指向按钮是一个实例变量和实例并不是一一对应的关系Button A = button1;
    A.Text = "Zswang 路过";变量A和变量button1都是指向同一个实例,所以A.Text改变button1也改变btn = new Button();  // 新建一个实例
    btn = new Button();  // 又新建一个实例,并不会影响前面创建的实例,只是btn的指向发生了变化
      

  2.   

    这也不矛盾啊,每个checkbox执行自己的事件(也许是我没有明白你的意思)
      

  3.   

    假如有类ClassA        ClassA x = new ClassA(); //引用变量x维护一个ClassA对象的句柄
            ClassA y = new ClassB(); //引用变量y维护另一个ClassA对象的句柄        y = x; //让y维护x维护的一个ClassA对象的句柄,也就是x和y同时维护一个ClassA对
                   //象的句柄。到现在,原先y维护的另一个ClassA对象就没有变量来维护它了,
                   //它也就成了“垃圾”。
            
    我给的代码里按理说也会造成同样的后果的,我又仔细想了想,可能是btn.Parent  =  this;这个语句使Control类的属性Controls(类型是Control.ControlCollection)暗中维护了Button对象的句柄了。Controls属性的实质是这个窗体的所以子对象控件的数组。
    所以你可以使用Controls[0]来维护第一个按钮对象的句柄。不知道我理解的对不对。
    感谢Zswang的提醒!!
      

  4.   

    不是所有的类都有句柄
    你说所得句柄我理解成内存资源(实例)
    当y = x后,原来y指向的实例就丢失了
    不过在.NET中编译器有垃圾收集处理的机制
    所有不同担心出现泄露如果是使用C++就要注意了,这样会导致内存泄露