DataContractSerializer 的问题 - 如何正确序列化从 List派生的对象?
请观察以下示例代码:
namespace A
{
[Serializable]
internal class ComplexObject<T> : List<T>, IEquatable<ComplexObject<T>>
where T : IEquatable<T>
{
private T m_state;
internal T State
{
get { return m_state; }
set { m_state = value; }
}
public bool Equals(ComplexObject<T> other)
{
// Implementation is omitted to save space.
}
}
public static class Program
{
public static void Main()
{
var obj = new ComplexObject<int>();
obj.State = 100;
var stream = new MemoryStream();
var serializer = new DataContractSerializer(obj.GetType());
serializer.WriteObject(stream, obj);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
var copy = (ComplexObject<int>)serializer.ReadObject(stream);
Debug.Assert(obj.Equals(copy));
}
}
}
请注意,ComplexObject
派生自 List
。
无论如何,最后的断言失败了。 将 [Serialized]
替换为 [CollectionDataContract]
并将 [DataMember]
附加到 m_state
会产生相同的负面结果。
就好像 DataContractSerializer 注意到该类是一个集合并选择忽略其其他状态。
请建议任何人如何解决此问题,因为:
- 我想对
ComplexObject
进行尽可能少的更改, - 由于与此无关的原因,我陷入了
DataContractSerializer
问题
提前非常感谢。
编辑:
public bool Equals(ComplexObject<T> other)
{
if (!m_state.Equals(other.m_state) || Count != other.Count)
{
return false;
}
bool result = true;
for (int i = 0; i < Count && (result = this[i].Equals(other[i])); ++i)
{
}
return result;
}
Observe the following sample code:
namespace A
{
[Serializable]
internal class ComplexObject<T> : List<T>, IEquatable<ComplexObject<T>>
where T : IEquatable<T>
{
private T m_state;
internal T State
{
get { return m_state; }
set { m_state = value; }
}
public bool Equals(ComplexObject<T> other)
{
// Implementation is omitted to save space.
}
}
public static class Program
{
public static void Main()
{
var obj = new ComplexObject<int>();
obj.State = 100;
var stream = new MemoryStream();
var serializer = new DataContractSerializer(obj.GetType());
serializer.WriteObject(stream, obj);
stream.Flush();
stream.Seek(0, SeekOrigin.Begin);
var copy = (ComplexObject<int>)serializer.ReadObject(stream);
Debug.Assert(obj.Equals(copy));
}
}
}
Note that ComplexObject<T>
derives from List<T>
.
Anyway, the last assertion fails.
Replacing [Serializable]
with [CollectionDataContract]
and attaching [DataMember]
to m_state
yields the same negative result.
It is as though the DataContractSerializer
notices that the class is a collection and chooses to ignore its other state.
Please advice anyone how to solve this issue given that:
- I would like to make as few changes to
ComplexObject<T>
as possible - I am stuck with
DataContractSerializer
for reasons irrelevant for this question
Thanks a lot in advance.
EDIT:
public bool Equals(ComplexObject<T> other)
{
if (!m_state.Equals(other.m_state) || Count != other.Count)
{
return false;
}
bool result = true;
for (int i = 0; i < Count && (result = this[i].Equals(other[i])); ++i)
{
}
return result;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
要正确序列化 List 结构,您必须使用 CollectionDataContract 属性,如下所示:
但是,CollectionDataContract 不允许序列化其他 DataMember。解决方法是避免从列表继承,而是将其设为成员变量,并可选择实现 ICollection,如下所示:
To correctly serialize a List structure, you have to use the CollectionDataContract attribute like so:
However, the CollectionDataContract doesn't allow for additional DataMembers to be serialized. The workaround would be to avoid inheriting from the list, but make it a member variable instead and optionally implement the ICollection, like so:
问题是当你试图返回对象的数组时 - 至少对我来说是这样。
我发现我需要创建一个对象类类型的列表,将该列表添加到 DataContractSerializer(typeof(mylist));
因此;
The problem is when you are trying to return an array of your object - at least it was for me.
I figure out that I needed to create a List of the type of my object class, add that list to the
DataContractSerrializer(typeof(mylist));
thus;
这是我用于克隆或序列化对象的一些代码。我很想知道您是否也有同样的问题。此代码仅返回一个对象类型,但您可以将结果转换为您的对象类型。
Here is some code I have for cloning or serializing an object. I would be curious to see if you have the same issues with this. This code simply returns an Object type, but you can cast the result to your object type.