我正在打开一个旧项目的代码分析。大多数的评论结果我都能理解,但CA2000:在失去作用域之前释放对象是很难得到正确的。
例如,来自ASP.Net页面的代码:
private void BuildTable()
{
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell td = new HtmlTableCell();
tr.Cells.Add(td);
// add some controls to 'td'
theTable.Rows.Insert(0, tr);
// 'theTable' is an HtmlTable control on the page
}提供CA消息:
CA2000 : Microsoft.Reliability :在方法'BuildTable()‘中,在对对象'tr’的所有引用超出作用域之前调用System.IDisposable.Dispose。 CA2000 : Microsoft.Reliability :在方法'BuildTable()‘中,对象'td’不是沿所有异常路径释放的。在所有对对象的引用超出作用域之前,在对象'td‘上调用System.IDisposable.Dispose。(以及添加到“td”中的控件的类似消息。)
我可以解决第二个问题:
private void BuildTable()
{
HtmlTableRow tr = new HtmlTableRow();
HtmlTableCell td = new HtmlTableCell();
try
{
tr.Cells.Add(td);
// add some controls to 'td'
td = null; // this line is only reached when there were no exceptions
}
finally
{
// only dispose if there were problems ('exception path')
if (td != null) td.Dispose();
}
theTable.Rows.Insert(0, tr);
}但我认为不可能解决'tr‘的信息。我不能处理它,因为在方法退出之后仍然需要它。
还是我错过了什么?
顺便说一句:将该theTable.Rows.Insert更改为theTable.Rows.Add将CA消息更改为“未沿所有异常路径处理”
发布于 2010-11-24 09:26:27
代码分析无法完全理解您的代码,只需警告您是否创建了一个似乎未被释放的一次性对象。在您的情况下,您应该关闭警告,因为在离开方法之前不应该释放对象。您可以通过自定义代码分析规则集来关闭整个项目的警告,也可以在每个具有此警告的方法上关闭警告,如果代码分析显然是错误的。
尽管如此,我建议您在处理using对象时使用IDisposable构造:
using (var tr = new HtmlTableRow()) {
using (var td = new HtmlTableCell()) {
tr.Cells.Add(td);
theTable.Rows.Insert(0, tr);
}
}(除了这段代码)是胡说八道,因为您不想释放刚才添加到表中的行和单元格。
发布于 2010-11-24 09:56:33
据我所知,您刚才已经表明,CA2000规则在大多数代码基础上并不十分有用,
由于上述这两种方法在普通代码中都很常见,我认为CA2000规则对大多数代码库都没有价值--当真正的问题出现时,有如此多的假阳性,您很可能会在50种情况下漏掉1种错误。
发布于 2011-06-04 16:50:37
这段代码将消除两个警告(我使用一个using( HtmlTable )来模拟您的全局HtmlTable成员……):
using (HtmlTable theTable = new HtmlTable())
{
HtmlTableRow tr = null;
try
{
HtmlTableCell td = null;
try
{
td = new HtmlTableCell();
// add some controls to 'td'
tr = new HtmlTableRow();
tr.Cells.Add(td);
/* td will now be disposed by tr.Dispose() */
td = null;
}
finally
{
if (td != null)
{
td.Dispose();
td = null;
}
}
theTable.Rows.Insert(0, tr);
/* tr will now be disposed by theTable.Dispose() */
tr = null;
}
finally
{
if (tr != null)
{
tr.Dispose();
tr = null;
}
}
}但是,我认为您将考虑使用一种使用子函数的方法来使代码更加清晰:
private static void createTable()
{
using (HtmlTable theTable = new HtmlTable())
{
createRows(theTable);
}
}
private static void createRows(HtmlTable theTable)
{
HtmlTableRow tr = null;
try
{
tr = new HtmlTableRow();
createCells(tr);
theTable.Rows.Insert(0, tr);
/* tr will now be disposed by theTable.Dispose() */
tr = null;
}
finally
{
if (tr != null)
{
tr.Dispose();
tr = null;
}
}
}
private static void createCells(HtmlTableRow tr)
{
HtmlTableCell td = null;
try
{
td = new HtmlTableCell();
// add some controls to 'td'
tr.Cells.Add(td);
/* td will now be disposed by tr.Dispose() */
td = null;
}
finally
{
if (td != null)
{
td.Dispose();
td = null;
}
}
}https://stackoverflow.com/questions/4264986
复制相似问题