MSOCAF 验证 - 不要在构造函数中调用可重写的方法

本文关键字:调用 可重写 方法 构造函数 验证 MSOCAF | 更新日期: 2023-09-27 18:31:04

我在MSOCAF中有此错误:

'ExcelChart.ExcelChart(ExcelDrawings, XmlNode, Uri, PackagePart, XmlDocument, XmlNode)' 包含一个调用链,导致对 由类定义的虚拟方法。查看以下调用堆栈 对于意外后果:

ExcelChart..ctor(ExcelDrawings, XmlNode, Uri, PackagePart, XmlDocument, XmlNode) ExcelChart.InitChartLoad(ExcelDrawings, XmlNode):Voi ExcelChart.GetChartType(String):eChartType

构造函数:

internal ExcelChart(ExcelDrawings drawings, XmlNode node, Uri uriChart, PackagePart part, XmlDocument chartXml, XmlNode chartNode) :
       base(drawings, node, "xdr:graphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr/@name")
   {
       UriChart = uriChart;
       Part = part;
       ChartXml = chartXml;
       _chartNode = chartNode;
       InitChartLoad(drawings, chartNode);
       ChartType = GetChartType(chartNode.LocalName);
   }

和错误的行:

XmlNode _chartNode = null;
    internal XmlNode ChartNode
    {
        get
        {
            return _chartNode;
        }
    }

两种方法:

private void InitChartLoad(ExcelDrawings drawings, XmlNode chartNode)
   {
       //SetChartType();
       bool isPivot = false;
       Init(drawings, chartNode);
       _chartSeries = new ExcelChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot /*ChartXml.SelectSingleNode(_chartPath, drawings.NameSpaceManager)*/);
       LoadAxis();
   }

internal virtual eChartType GetChartType(string name)
   {
       switch (name)
       {
           case "area3DChart":
               if(Grouping==eGrouping.Stacked)
               {
                   return eChartType.AreaStacked3D;
               }
               else if (Grouping == eGrouping.PercentStacked)
               {
                   return eChartType.AreaStacked1003D;
               }
               else
               {
                   return eChartType.Area3D;
               }
           case "areaChart":
               if (Grouping == eGrouping.Stacked)
               {
                   return eChartType.AreaStacked;
               }
               else if (Grouping == eGrouping.PercentStacked)
               {
                   return eChartType.AreaStacked100;
               }
               else
               {
                   return eChartType.Area;
               }
           case "bubbleChart":
               return eChartType.Bubble;
           case "doughnutChart":
               return eChartType.Doughnut;
           case "pie3DChart":
               return eChartType.Pie3D;
           case "pieChart":
               return eChartType.Pie;
           case "radarChart":
               return eChartType.Radar;
           case "scatterChart":
               return eChartType.XYScatter;
           case "surface3DChart":
           case "surfaceChart":
               return eChartType.Surface;
           case "stockChart":
               return eChartType.StockHLC;
           default:
               return 0;
       }           
   }

我在 CodePlex 中找到了此代码,并尝试解决 MSOCAF 返回的所有错误

MSOCAF 验证 - 不要在构造函数中调用可重写的方法

构造

函数ExcelChart()调用虚拟方法,GetChartType() 。派生类可以重写此方法,并使用在基类 (ExcelChart) 执行其构造函数时不存在或未初始化的数据。基类的实现者无法知道或防止从他或她的类派生的后续代码,并且从基类派生的人可能不知道基 ctor 调用他或她真正想要重写的虚拟方法。

这就是为什么编码指南经常禁止在 ctor 中调用虚拟方法。

请注意,虚拟方法的这种实现不同于C++,在中调用这些虚拟方法,这些虚拟方法位于执行其 ctor 的类的 vtable 中;也就是说,在嵌套的 ctor 中,每个 ctor 可以调用"相同"虚拟方法的不同版本。相比之下,在 C# 中,始终调用继承链中"派生最多"的实现。虽然这可能更简单且更可预测,但它与继承的想法有些反范式,并导致访问基类不访问的数据的危险。知道的。