我想保存某些类,由于 xml 序列化在我的情况下不会这样做,所以我手动将值保存到 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似乎不允许没有明显更糟和更复杂的解决方案。
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
方法的使用。由于Sum
实现只使用foreach
,最好写:
public int Sum(IEnumerable<int> parameter)
{
int tmp = 0;
foreach (int i in parameter)
{
tmp += i;
}
return i;
}
因此,您可以使用List<T>
的其他类型的Sum
:ObservableCollection<T>
...等。
它只是建议您不要将自己与方法签名中 XmlNode 的特定实现耦合。这允许您更改内部实现,而不会影响使用该类的任何内容。
如果需要具体类中的特定功能,建议可以忽略该警告。如果这是一个面向公众的 API,您应该尝试尽可能多地解耦,这将使您能够自由地更改实现,而更改方法签名的机会较小,从而迫使 API 的使用者更改其实现。
CA1059:成员不应公开某些具体类型
我发现使用XElements的LinqToXml正是我正在寻找的更简单,更强大的方式,更少的FxCop和接口问题。