FxCop投诉:暴露的具体xml类型和糟糕的改进

时间:2012-02-08 09:30:39

标签: c# xml xpath fxcop

我想保存某些类,因为xml-serialization在我的情况下不会这样做我将值手动保存到xml文档中。工作正常,但FxCop不喜欢它,因为FxCop通常给出了很好的建议和原因,为什么我不应该以某种方式做事我试着让它快乐。

这一次,我不明白这是一种改进。

这就是我所拥有的:

public void Save()
{
      XmlDocument doc = new XmlDocument();
      XmlNode XmlNodeJob = doc.CreateElement("Job");
      doc.AppendChild(XmlNodeJob);
      OtherclassSave2(XmlNodeJob);//Node as Parameter
 }

 public void OtherclassSave2(XmlNode node)
 {

 }

这就是FxCop所抱怨的: “修改成员'OtherclassSave2(XmlNode)',使其不再公开具体类型'XmlNode'。使用IXPathNavigable表示XML数据源。”

现在我的解决方案很棒:

    public void Save()
    {
        XmlDocument doc = new XmlDocument();
        XmlNode XmlNodeJob = doc.CreateElement("Job");
        doc.AppendChild(XmlNodeJob);
        OtherclassSave2(XmlNodeJob.CreateNavigator());//Interface from a node's navigator
    }

    public void OtherclassSave2(IXPathNavigable nav)
    {
        XmlNode node = (XmlNode)(nav.CreateNavigator().UnderlyingObject);

    }

这样我在另一个方法中得到了我的节点,FxCop很高兴,但我真的没有看到改进,我需要一个节点来添加内容,而不是要阅读。

我虽然将void SaveInThisNode(XmlNode)更改为 XmlNode GetMeTheNode()但是要通过CreateElements创建节点,我需要XmlDocument对象,我不允许用作参数,但我可以在每一步创建新的XmlDocuments,很好。

我的解决方案很简单,并且可以完成我希望它做的所有事情,但是FxCop似乎不允许解决方案显然更糟,更复杂。

3 个答案:

答案 0 :(得分:4)

FxCop说你应该使用界面而不是界面的具体实现。它可能检测到在您的OtherclassSave2方法中,参数nav可以用作IXPathNavigable而不指定具体实现(仅使用IXPathNavigable公开的成员)。

XmlNode实施IXPathNavigable 时,您应该可以写:

public void Save()
{
      XmlDocument doc = new XmlDocument();
      XmlNode XmlNodeJob = doc.CreateElement("Job");
      doc.AppendChild(XmlNodeJob);
      OtherclassSave2(XmlNodeJob);
 }

public void OtherclassSave2(IXPathNavigable node)
{
    // Deal with node using the interface only
}

只是为了澄清FxCop为什么这么说,这是FxCop检测到的问题最常见的例子:

说你有:

public int Sum(List<int> parameter)
{
    int tmp = 0;
    foreach (int i in parameter)
    {
        tmp += i;
    }

    return i;
}

List<int> lst = new List<int> {3, 4, 5};
int sum = Sum(lst);

由于Sum实现不使用List<T>类型的特定方法,因此将参数类型设置为List<int>并不是一个好主意,因为它会限制Sum的使用{1}}方法。由于Sum实现仅使用foreach,因此最好写:

public int Sum(IEnumerable<int> parameter)
{
    int tmp = 0;
    foreach (int i in parameter)
    {
        tmp += i;
    }

    return i;
}

因此,您可以使用SumList<T>等其他类型的电子邮件致电ObservableCollection<T>

答案 1 :(得分:2)

这只是建议您不要将自己与方法签名中的XmlNode的特定实现结合起来。这允许您更改内部实现,而不会影响使用该类的任何内容。

如果您需要具体类中的特定功能,建议您可以忽略该警告。如果这是一个面向公众的API,您应该尝试尽可能多地解耦,这样您就可以自由地更改实现,同时减少更改方法签名的可能性,从而迫使API的消费者更改其实现。

CA1059: Members should not expose certain concrete types

答案 2 :(得分:0)

我发现使用 XElements LinqToXml 正是我正在寻找一种更简单,更强大的方式,而且FxCop和界面问题更少。