0

又拔了我的头发。我整天都在看这个,无法弄清楚它是否可能,或者我做错了什么。

我创建了一个自定义对象集合。

 public class ObjectCollection<T> : IEnumerable<T>, IEnumerable where T : IUniqueObjectIdentifier
{

    protected List<T> List = new List<T>();
    protected Dictionary<Guid, int> Keys = new Dictionary<Guid, int>();
    protected Dictionary<int, Guid> Inverse = new Dictionary<int, Guid>();
    protected Dictionary<string, Guid> Name = new Dictionary<string, Guid>();
    public void Add(T item)
    {
        if (item is IUniqueObjectIdentifier itemIdentifier)
            if (!Keys.ContainsKey(itemIdentifier.Id))
            {
                List.Add(item);
                Keys.Add(itemIdentifier.Id, List.IndexOf(item));
                Inverse.Add(List.IndexOf(item), itemIdentifier.Id);
            }
    }
    public void Remove(T item)
    {
        if (item is IUniqueObjectIdentifier itemIdentifier)
            if (List.Contains(item))
            {
                int index = List.IndexOf(item);
                Guid key = Inverse[index];
                Keys.Remove(itemIdentifier.Id);
                Inverse.Remove(index);
                List.Remove(item);
            }
    }
    public void Remove(int index)
    {
        if (index < List.Count)
        {
            Guid key = Inverse[index];
            Keys.Remove(key);
            List.RemoveAt(index);
            Inverse.Remove(index);
        }
    }

    public void Remove(Guid key)
    {
        if (Keys.ContainsKey(key))
        {
            int index = Keys[key];
            Keys.Remove(key);
            List.RemoveAt(index);
            Inverse.Remove(index);
        }
    }

    public void Clear()
    {
        Keys.Clear();
        List.Clear();
        Inverse.Clear();
    }

    public int Count => List.Count;

    public bool Contains(T item)
    {
        return List.Contains(item);
    }

    public bool ContainsKey(Guid key)
    {
        return Keys.ContainsKey(key);
    }

    public T this[int index]
    {
        get
        {
            if (index < List.Count)
                return List[index];
            else
                return default(T);
        }
    }

    public T this[Guid key]
    {
        get
        {
            if (Keys.ContainsKey(key))
                return List[Keys[key]];
            else
                return default(T);
        }
    }

    public IEnumerator<T> GetEnumerator()
    {
        return List.GetEnumerator();
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    { return List.GetEnumerator(); }

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

然后我有一个事情:

public class Thing
{
    //Collections
    [XmlElement(ElementName = "Fields")]
    public Fields Fields { get; set; }

Fields 对象继承自 ObjectCollection:

[XmlRoot(ElementName = "Field")]
public class Fields:ObjectCollection<Field>
{

}

最后我有一个包含大量属性的字段类:

[XmlRoot(ElementName = "Field")]
public class Field : IUniqueObjectIdentifier
{
    [XmlElement(ElementName = "FLAGS")]
    public int Flags{ get; set; }

这似乎可行的唯一方法是,如果我像这样创建我的字段类:

[XmlRoot(ElementName = "Fields")]
public class Fields
{
    [XmlElement(ElementName = "Field")] private List<Field> Items { get; set; }
}

我讨厌。必须访问它,例如 Thing.Fields.Items.Add 而不是 Thing.Fields.Add。对我来说没有意义。

XML 是这样的:

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </Field>
    <Field ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

当我尝试反序列化它时,我只得到一个默认字段,即它添加到 objectcollection 但只有一个项目,并且它显然未能将该字段反序列化为它基本上是空的。

我试图看看我是否能弄清楚哪些属性可能会有所帮助,但我不确定。我还研究了创建自定义反序列化,但这似乎有点矫枉过正。

谁能帮我指出正确的方向。我只想要一个整洁的解决方案 - 复杂性最少!!!就像我们一样:-)

在我跳下当地码头之前,任何帮助将不胜感激。

干杯,

斯图。

4

1 回答 1

0

好的,我在我的帖子中稍微简化了示例:

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <AField ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </AField>
    <AField ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

至:

<Thing ID="BD825D4AD7F44C00B41E8827646EE196" Name="Thingy">
  <Fields>
    <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">
      <FLAGS>1</FLAGS>
    </Field>
    <Field ID="DAF609FFD05B413F9F9D0DA8DD241CB3" NAME="Fieldy2">
      <FLAGS>1</FLAGS>

和:

[XmlRoot(ElementName = "AField")]
public class Fields:ObjectCollection<Field>
{

}

至:

[XmlRoot(ElementName = "Field")]
public class Fields:ObjectCollection<Field>
{

}

答案是即使您指定了根,它也不会自动正确地映射到对象;您需要指定它 [XmlType("AField")],显然除非它们相同。在发布的案例中:XmlRoot(ElementName = "Field")] = <Field ID="02A5DA70FD94495E963DA5D7E414E30B" NAME="Fieldy">

所以这有效:

[XmlRoot(ElementName = "AField")]
[XmlType("AField")]
public class Fields:ObjectCollection<Field>
{

}

得到教训:

  1. 不要只是你的例子;按原样发布!
  2. 当你遇到问题时,将其分解为最小的行动来克服它。

我不禁觉得这有点倒退,因为您已经将它与根元素进行了映射,但是嘿。感谢 dbc 在这方面的帮助,否则我觉得我会在海底。为纯粹的努力而投票。

呸!

斯图。

于 2018-11-21T08:35:55.663 回答