在下有一个关于引用不是很明白的问题。

yoshubom 2006-09-27 12:03:25
我写了一个操作数据库的类如下:

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还有一用指着它所以它所属的那个类对象一直保留着还没有划进垃圾回收的队伍。请高手们指教。
...全文
213 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
avisnet 2006-09-27
  • 打赏
  • 举报
回复
你只要在使用一个对象,它就一直有效的
在这个对象不被引用时才会被回收
ClementDik 2006-09-27
  • 打赏
  • 举报
回复
注意你的代码:

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;
那么,刚才创建的对象就变成垃圾了。
wsxqaz 2006-09-27
  • 打赏
  • 举报
回复
你指针一直拉着这个东西怎么会被销毁,你等于应该只是地址引用又不是值引用,垃圾回收只在某个对象没有一个指针指向他时才回收
kssys 2006-09-27
  • 打赏
  • 举报
回复
在没有引用的时候销毁,楼上的代码还保持着引用。
yoshubom 2006-09-27
  • 打赏
  • 举报
回复
多谢剑问天和各位的耐心教导,小弟终于有所领悟了。
yoshubom 2006-09-27
  • 打赏
  • 举报
回复
那么我new clsDB()的这个对象在函数OperaDB()结束之后会不会被视为垃圾呢?

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧