【问题标题】:Ist there a way to serialize public properties of a class that implements ICollection有没有办法序列化实现 ICollection 的类的公共属性
【发布时间】:2013-05-29 09:24:31
【问题描述】:

为了方便,我有一个实现 ICollection 的类。当类被序列化为 XML 时,所有公共属性都被跳过,只有实际的集合被序列化。我从 MSDN 阅读了以下内容

实现 ICollection 或 IEnumerable 的类。

  • 仅对集合进行序列化,而不对公共属性进行序列化。

有没有办法解决这个问题?有没有办法让一个类实现 ICollection 并且仍然会输出公共属性?还是我必须使用 XmlWriter 自己做?

以防万一需要示例。

public class Batch: ICollection<Foo>
{
    public string Bar { get; set; }
    
    public int Baz { get; set; }
    
    public List<Foo> Foos { get; private set; }
    
    public IEnumerator<Foo> GetEnumerator()
    {
        return Foos.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return Foos.GetEnumerator();
    }

    public void Add(Foo item)
    {
        Foos.Add(item);
    }

    public void Clear()
    {
        Foos.Clear();
    }

    public bool Contains(Foo item)
    {
        return Foos.Contains(item);
    }

    public void CopyTo(Foo[] array, int arrayIndex)
    {
        Foos.CopyTo(array, arrayIndex);
    }

    public bool Remove(Foo item)
    {
        return Foos.Remove(item);
    }

    public int Count { get { return Foos.Count; } }

    public bool IsReadOnly { get { return false; } }
}

之所以这样,是因为在我的代码的另一部分中,我正在处理事物的集合。 IList IList 等。但是对于批次,有适用于每个 Foo 的信息,但对于一个特定批次的每个 foo,该信息是相同的。可能像批次 ID 或 Created DateTime。我希望能够在我的代码的某些部分以相同的方式处理我的批次和其他集合,因为我只关心一个集合并且有一个计数。我不在乎某些信息与该集合中的每个项目都相同。

我想这样做的原因是为了序列化。我试图删除多余的信息。如果有另一种方式来组织我的课程,我不会失去那个非常重要的计数,那么我会全神贯注。我希望避免创建另一个只包含这样一个简单事物的计数的界面。感觉很脏,但它可能是正确的。

【问题讨论】:

    标签: c# .net xml-serialization


    【解决方案1】:

    不,基本上。这不是 XmlSerializer 独有的 - 框架的大部分将 collectionselements 视为相互排斥的。我的建议:不要这样做。拥有一个或者集合xor元素的东西。

    这并不意味着格式必须改变 - 您通常可以封装一个列表(而不是成为一个列表)并使用[XmlElement("someName")]来获得相同的类型输出,例如:

    public class PeopleWrapper
    {
        [XmlAttribute("someValue")]
        public int SomeValue { get; set; }
    
        private readonly List<Person> people = new List<Person>();
        [XmlElement("person")]
        public List<Person> Items { get { return people; } }
    }
    

    那么如果另一个类有:

    public PeopleWrapper People { get; set; }
    

    你会在 xml 中得到:

    <People someValue="123">
        <person>...</person>
        <person>...</person>
        <person>...</person>
    </People>
    

    【讨论】:

    • 我做了一些修改。这会类似于 SqlCommand 具有 SqlParameterCollection 的方式吗?
    • @uriDium 我猜...取决于您想进行类比的程度。但实际上,SqlCommand 具有 参数集合作为属性 (.Parameters) - 它本身 不是参数集合。查看您的编辑,Batch 拥有 Foo 的集合 - 称为 .Foos。其他所有内容(所有添加/包含/GetEnumerator)实际上是Foos 的一部分,不属于Batch IMO。如果是我,Batch 将只是 .Foos.Bar.Baz
    【解决方案2】:

    在这种情况下,您必须自己实现IXmlSerializable。有关这方面的更多信息,请查看at MSDN 和/或此SO answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 2017-08-06
      • 1970-01-01
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多