5

在现有项目上运行代码分析时,我遇到了消息不要公开通用列表集合属性应该是只读的。但是,该类用于读取/写入 xml 配置文件。是否可以让这个类符合CA1002CA2227或者我是否必须为 XML 相关类禁止这些规则(项目中有很多)?

编辑

更改List<string>为已Collection<string>解决的 CA1002。仍然不知道如何解决 CA2227 并且仍然能够(反)序列化整个事情。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Xml.Serialization;

/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage
{
    /// <summary>
    /// Gets or sets the list of executers.
    /// </summary>
    [XmlArray("Executers")]
    [XmlArrayItem("Executer")]
    public Collection<string> Executers { get; set; }

    /// <summary>
    /// Gets or sets the list of IPG prefixes.
    /// </summary>
    [XmlArray("IpgPrefixes")]
    [XmlArrayItem("IpgPrefix")]
    public Collection<string> IpgPrefixes { get; set; }

}

读取 xml 文件:

    public static ConfigurationStorage LoadConfiguration()
    {
        if (File.Exists(ConfigFile))
        {
            try
            {
                using (TextReader r = new StreamReader(ConfigFile))
                {
                    var s = new XmlSerializer(typeof(ConfigurationStorage));
                    var config = (ConfigurationStorage)s.Deserialize(r);
                    return config;
                }
            }
            catch (InvalidOperationException invalidOperationException)
            {
                throw new StorageException(
                    "An error occurred while deserializing the configuration XML file.", invalidOperationException);
            }
        }
    }
4

2 回答 2

5

怎么样:

/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage {
  /// <summary>
  /// Gets or sets the list of executers.
  /// </summary>
  [XmlArray("Executers")]
  [XmlArrayItem("Executer")]
  public Collection<string> Executers { get; private set; }

  /// <summary>
  /// Gets or sets the list of IPG prefixes.
  /// </summary>
  [XmlArray("IpgPrefixes")]
  [XmlArrayItem("IpgPrefix")]
  public Collection<string> IpgPrefixes { get; private set; }

  public ConfigurationStorage() {
    Executers = new Collection<string>();
    IpgPrefixes = new Collection<string>();
  }
}

这仍然适用于 xml 序列化/反序列化。

于 2013-08-08T08:58:31.117 回答
0

如果您阅读MSDN 上的文档,您会看到一条注释:

XmlSerializer 对实现 IEnumerable 或 ICollection 的类进行特殊处理。实现 IEnumerable 的类必须实现采用单个参数的公共 Add 方法。Add 方法的参数必须与从 GetEnumerator 返回的值的 Current 属性返回的类型相同,或者该类型的基数之一。除了 IEnumerable 之外,实现 ICollection 的类(例如 CollectionBase)必须具有采用整数的公共 Item 索引属性(C# 中的索引器),并且必须具有整数类型的公共 Count 属性。Add 方法的参数必须与从 Item 属性返回的类型相同,或者是该类型的基数之一。对于实现 ICollection 的类,要序列化的值是从索引的 Item 属性中检索的,

因此,我认为,如果您符合这种特殊处理,您将拥有更好的代码,它可以与XmlSerializer.规则。

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

/// <summary>
/// Class containing the Configuration Storage
/// </summary>
[XmlRoot("Configuration")]
public class ConfigurationStorage
{
    // The executers.
    private readonly ICollection<string> executers = new List<string>();

    // The IPG prefixes.
    private readonly ICollection<string> ipgPrefixes = new List<string>();

    /// <summary>
    /// Gets the list of executers.
    /// </summary>
    [XmlArray("Executers")]
    [XmlArrayItem("Executer")]
    public ICollection<string> Executers
    { 
        get
        {
            return this.executers;
        }
    }

    /// <summary>
    /// Gets the list of IPG prefixes.
    /// </summary>
    [XmlArray("IpgPrefixes")]
    [XmlArrayItem("IpgPrefix")]
    public ICollection<string> IpgPrefixes
    { 
        get
        {
            return this.ipgPrefixes;
        }
    }
}
于 2013-08-08T09:19:34.320 回答