代码分析:TableCell如何攻克CA2000

Posted

技术标签:

【中文标题】代码分析:TableCell如何攻克CA2000【英文标题】:Code Analysis: How to overcome CA2000 for TableCell 【发布时间】:2012-11-16 09:18:10 【问题描述】:

我有以下带有三个 CA2000 警告的代码。对于 cellFirst 变量,我可以通过使用“使用”块来克服这个问题。但是对于其他两个 headercells,控件是在辅助函数中创建的。

CA2000 : Microsoft.Reliability : 在 GetTableCell(string, int, string, string) 方法中,对象“lnkHide”并未沿所有异常路径进行处理。在对对象“lnkHide”的所有引用超出范围之前调用 System.IDisposable.Dispose。

CA2000:Microsoft.Reliability:在方法 GetTableCell(string, int, string, string) 中,对象“ltlText”并未沿所有异常路径进行处理。在对对象“ltlText”的所有引用超出范围之前调用 System.IDisposable.Dispose。

CA2000 : Microsoft.Reliability : 在方法 GetTableCell(string, int, string, string) 中,对象“newCell”并未沿所有异常路径进行处理。在对对象“newCell”的所有引用超出范围之前调用 System.IDisposable.Dispose。

代码

    protected void grdTransactions_RowCreated(object sender, GridViewRowEventArgs e)
    

        if (e != null)
        
            if (e.Row.RowType == DataControlRowType.Header)
            
                GridViewRow newHeaderRow = null;
                try
                

                    newHeaderRow = new GridViewRow(-1, -1, DataControlRowType.Header, DataControlRowState.Normal);

                    using (TableHeaderCell cellFirst = new TableHeaderCell())
                    
                        cellFirst.ColumnSpan = 1;
                        cellFirst.Text = "FIRST";
                        newHeaderRow.Cells.Add(cellFirst);
                    


                    //Associate 
                    #region Associate

                    TableHeaderCell cellAssociate = GetTableCell("tableColGroupAssociate", 4, "associateHide", "Associate Transaction Info");

                    #endregion

                    //Financial 
                    #region Financial

                    TableHeaderCell cellFinancial = GetTableCell("tableColGroupTransaction", 5, "financialHide", "Financial Transaction Info");


                    #endregion

                    newHeaderRow.Cells.Add(cellAssociate);
                    newHeaderRow.Cells.Add(cellFinancial);
                    ((GridView)sender).Controls[0].Controls.AddAt(0, newHeaderRow);

                
                finally
                
                    if (newHeaderRow != null)
                    
                        newHeaderRow.Dispose();
                        newHeaderRow = null;
                    
                

            
        




    

    private static TableHeaderCell GetTableCell(string cssClassName, int colSpan, string hideClassName, string displayName)
    
        TableHeaderCell newCell = new TableHeaderCell();
        newCell.ColumnSpan = colSpan;
        newCell.CssClass = cssClassName;

        LiteralControl ltlText = new LiteralControl();
        ltlText.Text = displayName;
        newCell.Controls.Add(ltlText);

        HyperLink lnkHide = new HyperLink();
        lnkHide.Text = SupportToolUIResource.HideLinkText;
        lnkHide.CssClass = hideClassName;
        lnkHide.Target = SupportToolUIResource.HideLinkTarget;
        newCell.Controls.Add(lnkHide);

        return newCell;
    

参考

    To Dispose or not to Dispose (CA2000)

更新代码

使用块来克服警告

  using (TableHeaderCell cellAssociate = new TableHeaderCell())
                    
                        GetTableCell(cellAssociate,"tableColGroupAssociate", 4, "associateHide", "Associate Transaction Info");
                        newHeaderRow.Cells.Add(cellAssociate);
                    


     private static void GetTableCell(TableHeaderCell cellAssociate, string cssClassName, int colSpan, string hideClassName, string displayName)
    
        cellAssociate.ColumnSpan = colSpan;
        cellAssociate.CssClass = cssClassName;

        using (LiteralControl ltlText = new LiteralControl())
        
            ltlText.Text = displayName;
            cellAssociate.Controls.Add(ltlText);
        

        using (HyperLink lnkHide = new HyperLink())
        
            lnkHide.Text = SupportToolUIResource.HideLinkText;
            lnkHide.CssClass = hideClassName;
            lnkHide.Target = SupportToolUIResource.HideLinkTarget;
            cellAssociate.Controls.Add(lnkHide);
        


    

问题

应用程序“使用”块(如更新的代码所示)中是否有任何陷阱来克服警告?

【问题讨论】:

与您已链接的问题所接受的答案相同。这是基于启发式的警告;如果你确定你是对的,就压制它。 FxCop 长期无法理解控件的处理方式。它给你带来了麻烦,你需要删除 finally 块并摆脱 using 语句。释放 GridView 时会自动释放单元格。 GridView 会在其父级被释放时自动释放。等等。后来,在这个方法停止运行之后。 @HansPassant 应用程序“使用”块(如更新的代码所示)中是否有任何陷阱来克服警告? @Lijo 是的,绝对不要那样做。 CA2000 仅适用于您的代码控制生命周期的对象 - 因为您您创建的所有对象都交给GridView,所以它不是 i> 你对Dispose他们的责任。 【参考方案1】:

请阅读What’s wrong with use of “Using” block on Webcontrols? 以获得对此的一些见解。另请参阅Why would I need to call dispose on ASP.NET Controls?

一些兴趣点是(来自上面的帖子):

    我们需要做的是确保添加的新控件在 Controls 的集合中,以便在释放 Page 时释放它。 控制对象实现 IDisposable 接口。每个父控件都可以对其所有子控件调用 Dispose 任何实现 IDisposable 并具有在处置过程中实际清理的状态数据的正确编写的对象,如果在处置后访问其任何公共/受保护/内部属性或方法,则应引发 ObjectDisposedException。 (假设在 Dispose 被调用后处于无效状态。)如果某些类型实际上没有任何要清理的内容,则将忽略此规则,并且不必担心无效状态。

【讨论】:

以上是关于代码分析:TableCell如何攻克CA2000的主要内容,如果未能解决你的问题,请参考以下文章

使用链式构造函数避免代码分析 CA2000 警告?

代码分析警告 CA2000:在对象“new ContainerControlledLifetimeManager()”上调用 Dispose

CA2000:Microsoft.Reliability 对象未沿所有异常路径进行处理

卡内的 TableCell 文本在 React 中溢出

“CA2000 在失去范围之前处理对象”,原因不明

为啥 FxCop 不报告 CA2000 对于这种未处置的类实例的琐碎情况?