我写了一个操作数据库的类如下:using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;namespace RCTest2
{
    class clsDB
    {        
        
        public DataTable OperaDB(string strCom)
        {
            string strConn = "server=.;uid=sa;pwd=sa;database=liang";            SqlDataReader dRead;
            SqlConnection conn = new SqlConnection(strConn);
            SqlCommand cmd;
            DataTable dt=new DataTable();            //strCom 为要执行的SQL语句
            conn.Open();
            cmd = new SqlCommand(strCom,conn);
            dRead = cmd.ExecuteReader();
            dt.Load(dRead);
            conn.Close();            return dt;
        }
    }
}然后在程序里是这样使用的string strCom = "select * from generalTable";dataGridView1.DataSource = (new clsDB()).OperaDB(strCom);令我感到奇怪的是在OperaDB函数里面new的DataTable在函数结束的时候不是应该像其它函数内部变量被销毁吗?那么引用指向一个被销毁的东西为什么还有数据呢?还是因为这个datatable还有一用指着它所以它所属的那个类对象一直保留着还没有划进垃圾回收的队伍。请高手们指教。

解决方案 »

  1.   

    注意你的代码:DataTable dt=new DataTable();
    表示 dt 指向一个新建的DataTable对象。注意,dt自己也是要占用内存的,它存储着指向的对象的地址。return dt;
    此时将dt的值(也就是创建的DataTable对象的地址)作为返回值返回。
    然后dt确实被销毁了。但是这里只是销毁dt,而没有销毁dt指向的对象。
    如果原来被dt引用的对象,此时没有被其他变量引用,那么稍后它将被回收(也就是销毁掉)。dataGridView1.DataSource = (new clsDB()).OperaDB(strCom);
    而这句话,表示把OperaDB(strCom)的返回值(也就是刚才说dt的值,即创建的DataTable对象的地址)赋值给dataGridView1.DataSource。
    这个你当然明白,但是,请注意,从始至终,我们只有一个DataTable对象。被传递的只是这个对象的地址。
    于是,在dt被销毁后,由于dataGridView1.DataSource保持着对这个对象的引用,因此,这个对象是不会被回收(即销毁)的。如果你在之后加上下面这句:
    dataGridView1.DataSource = null;
    那么,刚才创建的对象就变成垃圾了。
      

  2.   

    那么我new clsDB()的这个对象在函数OperaDB()结束之后会不会被视为垃圾呢?