我有一些看起来像这样的代码:
Object o;
using (SqlConnection sql = GetSqlConnection) {
using (SqlCommand sqlCommand = GetSqlCommand()) {
using (Datareader dr = GetDataReader()) {
o = new Object();
while (dr.read()) {
//do something
}
}
if (o == null) // RESHARPER SAYS THAT THIS WILL ALWAYS BE TRUE
//do something
}
}
我检查o == null
的地方,ReSharper说这个命令永远都是真的。我不明白这种行为;对using
块中初始化的所有对象进行处理,或仅使用using
语句创建的对象。
答案 0 :(得分:2)
当关闭using块时,它将在该对象上调用Dispose(),这取决于IDisposable的实现,可以将对象设置为null。但是,在您的情况下,“o”不是IDisposable或在使用块中,并且我愿意相信ReSharper在这种情况下有一个错误,因为当我在安装中有完全相同的代码时,它会提示我替换
if(o == null)
错误,恰恰与您的问题相反。
答案 1 :(得分:1)
初始化“using”块中的对象是否将其置于外部 块?
否即可。 Here is proof.
您使用的对象当然会被处理(这是整个使用的重点),但是在块内完成的事情不会受到影响。不过,这是一个新的范围,因此您可以通过此代码获得警告:
Object o;
using (SqlConnection sql = GetSqlConnection) {
using (SqlCommand sqlCommand = GetSqlCommand()) {
using (Datareader dr = GetDataReader()) {
Object o = new Object();
while (dr.read()) {
//do something
}
}
if (o == null) // RESHARPER SAYS THAT THIS WILL ALWAYS BE TRUE
//do something
}
}
(注意内部范围内第二个对象o的声明)。
答案 2 :(得分:1)
如果您的代码完全按照书面形式编写,并且Resharper真的抱怨您指定的行,那么这是错误的。
事实上,ReSharper完全倒退了:比较是多余的,因为它永远是真的。您立即将o
设置为new Object()
,因此它永远不会是null
。除了您在开始语句中输入的变量之外,using
块对变量的值没有影响。在离开using
块时,通过在其上调用IDisposable.Dispose
来处理该实例,并且它超出范围。
但是,我确实想纠正您似乎遇到的一个巨大误解: 处置对象时不会将其设置为null 。以下代码 在尝试关闭已经处置的对象时仍然会崩溃:
var conn = new SqlConnection(GetConnectionString());
conn.Open();
conn.Dispose();
if (conn != null)
{
conn.Close();
}
“被处置”是适用于对象实例的条件;这意味着他们的资源已被清理干净,无法再安全使用。 “为空”是适用于变量的条件;这意味着他们不会引用他们定义类型的任何实例,无论是处置还是其他。
using
关键字和IDisposable
接口用于管理对象实例的is-dispos-of状态。它们对程序中变量的is-a-null值状态没有影响。