当我运行代码分析工具时,我得到以下内容:
警告1 CA2000:Microsoft.Reliability:在方法“Class1.test.testMethod()”中,对象“dt”未沿所有异常路径放置。对所有对它的引用超出范围之前,在对象'dt'上调用System.IDisposable.Dispose。 如何解决警告??
public void testMethod()
{
DataTable dt = new DataTable();
DataTable dt1= new DataTable();
try
{
if (dt.Rows.Count == 0)
{
dt1.Merge(dt);
}
}
catch
{
throw;
}
finally
{
if (dt != null) dt.Dispose();
if (dt1 != null) dt1.Dispose();
}
}
答案 0 :(得分:5)
不确定为什么会收到该错误,但您可以在方法中尝试using
语句块并查看错误是否消失。试试吧:
public void testMethod()
{
using (DataTable dt = new DataTable())
using (DataView dv = new DataView(dt))
{
//your work
}
}
答案 1 :(得分:2)
来自Dispose objects before losing scope
如果一次性物品没有明确处理 对它的引用超出了范围,该对象将被置于某些位置 垃圾收集器运行终结器时的不确定时间 物体。因为可能会发生可能阻止的异常事件 从运行的对象的终结器,对象应该是 明确地代替了。
要修复违反此规则的行为,请致电
System.IDisposable.Dispose
所有引用之前的对象都超出了范围。请注意,您可以使用using语句(在Visual Basic中使用)来 包装实现
IDisposable
的对象。对象包裹在此 方式将在使用区块结束时自动处理。
using (DataTable dt = new DataTable())
using (DataView dv = new DataView(dt))
{
}
答案 2 :(得分:2)
在代码的第7行中,您创建了一个未使用的虚拟DataTable。编译器抱怨DataTable和DataView对象。更改下面的代码,它将起作用。
public class Class1
{
public class test
{
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
// dt must be assigned a value only within the try block
dt = new DataTable(dt);
dv = new DataView(dt);
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
}
<强>更新强>
如果同时处理dt
和dv
,您将获得CA2202 error。这是因为dt
被处置了两次。处置dt
时处置dv
和处理null
一次。为避免这种情况,您必须在try / catch块的末尾将dt
分配给 try
{
dt = new DataTable(dt);
dv = new DataView(dt);
dt=null;
}
。
{{1}}
答案 3 :(得分:1)
我怀疑错误正在发生,因为您要创建两个DataView
,并且只会丢弃其中一个:您将dv
初始化为新的DataView
然后分配另一个try
在finally
区块。当您点击DataView dv = new DataView ()
时,初始分配中的那个将不会被处理,因为您没有参考它。
修改声明public void testMethod()
{
DataTable dt = new DataTable();
DataView dv = null;
try
{
dv = new DataView(dt);
}
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
以声明变量,而不是初始化它:
dv
注意:这会直接修复您的第二条错误消息(约dt
),并间接解决第一条错误消息(约dv
)。引发第一个错误是因为,如果dt
的冗余初始化是抛出异常,则{{1}}将不会被处理 - 因此删除该初始化会修复错误。
答案 4 :(得分:1)
您的示例代码所展示的确切内容尚不清楚。
但是,如果您在遵循MSDN推荐模式时尝试在CA2000上清除误报,则有一些已知的补救措施。我概述了两个案例here,其中一个简单的代码更改使代码分析能够识别推荐的模式:
IDisposable
。IDisposable
必须是函数的返回值。 答案 5 :(得分:0)
可能是因为DataTable初始化器理论上可能会在处置之前中断。您可以尝试使用null初始化它,并在try块中使用新的DataTable实例进行初始化。毕竟你终于可以进行可空的测试了。
像
这样的东西public class Class1
{
public class test
{
public void testMethod()
{
DataTable dt = null;
try
{
dt = new DataTable();
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
}
}
}
}
答案 6 :(得分:0)
因为您在try块之外初始化dt而发生。
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
dt = new DataTable();
dv = new DataView(dt);
}
catch
{
}
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
如其他答案中所述,您也可以使用块代替try ... finally。
public void testMethod()
{
using (DataTable dt = new DataTable())
{
using (DataTable dv = new DataView(dt))
{
}
}
}
一个问题:您是否打算将test
类设为Class1
的嵌套类?
答案 7 :(得分:0)
public class test
{
public void testMethod()
{
DataTable dt = null;
DataView dv = null;
try
{
dv = new DataView(dt);
}
catch
{ }
finally
{
if (dt != null) dt.Dispose();
if (dv != null) dv.Dispose();
}
}
}
}