(如so):在方法中创建它并将其分配给字段。将该字段传递给方法,然后将其分配给using-语句的一个变量(这是调用的唯一Dispose )。
SqlCommand CreateSqlCommand()
{
SqlCommand cmd1 = new SqlCommand();
return cmd1;
}
void UseSqlCommand(SqlCommand cmd4)
{
using (SqlCommand cmd3 = cmd4)//Is this using-statement enough?
{
//use cmd3 here...
}
}并使用:
SqlCommand cmd2 = CreateSqlCommand();
UseSqlCommand(cmd2);额外详细信息:GC会在下一轮中收集所有这些变量吗?为什么不-见大卫·M·基恩的答案这里。
编辑
我增加了
cmd2.CommandText = "";在前面(最后)行之后。也没有抛出错误。
为什么?它应该已经处理好了!,别管了。处理过的对象可以被引用..。
请不要把注意力集中在这个例子上,而是要关注这个问题本身。谢谢,
发布于 2013-06-19 20:29:44
是的,using语句将在块对引用的变量完成后调用Dispose()。这是一件好事和坏事,假设您创建了一个sql命令并将结果存储在变量cmd中,然后将该变量传递给另一个使用和处理cmd的方法。现在,您被一个被释放的变量卡住了,如果您尝试使用它,它可能会抛出一个ObjectDisposedException。
SqlCommand cmd = CreateSqlCommand();
UseSqlCommand(cmd);
//Uh oh, cmd can still be used, what if I tried to call UseSqlCommand(cmd) again?在方法之外处置该物体将更加明确和安全(如Jord o张贴的那样)。
using(SqlCommand cmd = CreateSqlCommand())
{
UseSqlCommand(cmd);
}现在,您可以完全控制对象并限制其范围。
发布于 2013-06-19 20:05:53
从外部控制using的范围:
using (SqlCommand cmd2 = CreateSqlCommand()) {
UseSqlCommand(cmd2);
}
...
void UseSqlCommand(SqlCommand cmd4) {
// use cmd4 here...
}也许把UseSqlCommand重命名为不同的东西,比如ExecuteSqlCommand。
发布于 2013-06-20 15:26:00
using语句的目的不是要释放变量,而是处理对象实例。变量通常用于标识对象实例,但是引用类型变量不包含对象--它们持有“对象标识符”。
如果有人说(例如var myPort = new System.Io.Ports.SerialPort("COM1", ...); myPort.Open() ),SerialPort对象将要求系统允许它使用COM1串口,并且在进一步通知之前不让其他人使用它。系统将为该端口生成一个句柄,并设置一些标志,以便只允许具有该句柄的代码使用该端口。一旦创建了对象(假设系统任意为其分配ID #8675309),系统将将该ID存储到变量myPort中。
当代码不再需要使用该串口时,重要的是有人告诉对象#8675309不再需要它,因此它可以反过来告诉系统它应该使COM1可供其他应用程序使用。这通常是通过对一个保存对对象#8675309的引用的变量调用Dispose来完成的。一旦完成,每个包含对对象#8675309的引用的变量都将保存对其Dispose方法已被调用的对象的引用。注意,Dispose方法实际上不会影响这些变量中的任何一个(除非它们是在方法本身的代码中重写的)。在调用之前保存"object #8675309“的任何变量在调用之后都会继续这样做。对象将释放其串行端口,因此存储这些变量的引用将不再有多大用处,使用这些变量的代码可能希望清除这些变量,但SerialPort对象不会关心任何方式。
https://stackoverflow.com/questions/17200039
复制相似问题