由于SqlConnection
和SqlCommand
实施IDisposable
,我将它们包含在using
语句中。
但是,我在方法中创建它们然后将它们传递给using
语句,因此想知道using
的右括号是否会处理SqlCommand
由方法创建。
所以我尝试了这个:
private void button1_Click(object sender, EventArgs e)
{
SqlCommand command = new SqlCommand();
command.CommandTimeout = 10;
command.Disposed += s_Disposed;
using (SqlCommand tempCommand = command) { }//This is where even "command" is supposed to get disposed.
Text = command.CommandTimeout.ToString();
}
void s_Disposed(object sender, EventArgs e)
{
MessageBox.Show("Disposed");
}
并且惊讶地发现MessageBox
确实表明它被处置了,但文本是“10”。
为什么?
答案 0 :(得分:3)
通常,实现IDisposable
的对象(例如SqlConnection
)会这样做,因为宇宙中的某些东西(如SQL服务器)已被要求代表他们做某事(例如打开)并保持连接)并将继续这样做,直到另有指示。通常,IDisposable
对象需要让那些外部事物代表它行动,如果它要遵守它希望接收的请求(例如执行SQL操作)。 Dispose
的目的不是要实际销毁调用它的对象,而是让对象知道,因为没有其他人需要它,它应该反过来允许任何外部实体做任何事情它代表知道他们不再需要这样做(例如,因为没有人会要求SqlConnection
执行更多请求,所以不再需要服务器保持连接打开它。)
如果在一个对象上调用Dispose
后,它被要求做一些需要外部实体帮助的东西,这个东西不再可用,那么对象最好抛出{{1}本身比以某种其他方式失败的动作。另一方面,如果要求对象做一些可以在不使用外部实体的情况下完美地完成的事情,那么它通常是适当的。使用ObjectDisposedException
对象的代码通常应该避免在IDisposable
之后使用未明确记录为仍然可用的任何成员,并且应该避免假设Dispose
之后仍然有用的成员在一个版本的课程上总会如此。尽管如此,在许多情况下,一个班级指定特定成员可以在Dispose
之后使用,而不是通过确保他们不能成功的方式更好。
答案 1 :(得分:1)
它确实正确处理了SqlCommand
实例,并且无论你有多少引用都没关系。无论如何,他们都指向同一个实例。
但是,即使在已处置的对象上,CommandTimeout
也不会引发异常。