【发布时间】:2018-11-20 17:48:07
【问题描述】:
再次拔掉我的头发。我花了一整天的时间看这个,不知道它是否可能,或者我做错了什么。
我创建了一个自定义对象集合。
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 但只有一个项目,并且它显然未能将该字段反序列化,因为它基本上是空的。
我试图看看我是否能弄清楚哪些属性可能会有所帮助,但我不确定。我还研究了创建自定义反序列化,但这似乎有点过头了。
谁能帮我指出正确的方向。我只想要一个整洁的解决方案 - 复杂性最少!!!就像我们一样:-)
在我跳下当地码头之前,任何帮助都将不胜感激。
干杯,
斯图。
【问题讨论】:
-
能否请edit 分享minimal reproducible example 的问题?因为它是您的代码无法编译,因为它缺少
IUniqueObjectIdentifier的定义。我在这里做了一些猜测:dotnetfiddle.net/YBHxvA,但我们仍然需要一个完整的示例来提供帮助。 -
无法复制,请参阅dotnetfiddle.net/4xLiar。根据我对
IUniqueObjectIdentifier的猜测,Fields集合已成功序列化和反序列化。 -
感谢 dbc,您对接口的猜测是正确的: public interface IUniqueObjectIdentifier { Guid Id { get;放; } }
-
另外,您已将 xml 中的 Field 元素作为“Fields”,但错过了父“Fields”元素。谢谢你看这个。这有帮助吗?
-
我已经更新了,这似乎有效,但在我的代码中却没有:-( dotnetfiddle.net/ArFLmo
标签: c# serialization custom-collection