请注意以下示例代码:
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<T>
来自List<T>
。
无论如何,最后一个断言失败了。
将[Serializable]
替换为[CollectionDataContract]
并将[DataMember]
附加到m_state
会产生相同的否定结果。
好像DataContractSerializer
注意到该类是一个集合,并选择忽略其他状态。
请告知任何人如何解决这个问题:
ComplexObject<T>
进行更改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;
}
答案 0 :(得分:2)
要正确序列化List结构,您必须使用 CollectionDataContract 属性,如下所示:
[CollectionDataContract]
[Serializable]
internal class ComplexObject<T> : List<T>, IEquatable<ComplexObject<T>>
where T : IEquatable<T>
但是,CollectionDataContract不允许序列化其他DataMembers。解决方法是避免从列表继承,而是使其成为成员变量,并可选择实现ICollection,如下所示:
[DataContract]
[Serializable]
internal class ComplexObject<T> : ICollection<T>, IEquatable<ComplexObject<T>>
where T : IEquatable<T>
{
private T m_state;
[DataMember]
public T State
{
get { return m_state; }
set { m_state = value; }
}
private List<T> m_List = new List<T>();
[DataMember]
public List<T> List
{
get { return m_List; }
set { m_List = value; }
}
public bool Equals(ComplexObject<T> other)
{
if (!other.State.Equals(State))
return false;
if (other.List.Count != List.Count)
return false;
for (int i = 0; i < other.List.Count;i++)
{
if (!other.List[i].Equals(List[i]))
return false;
}
return true;
}
// ICollection members left out to save space
// helper methods to wrap around the List to decrease the amount
// of refactoring work you would have to do
public void Add(T item)
{
List.Add(item);
}
public bool Remove(T item)
{
return List.Remove(item);
}
public T this[int index]
{
get { return List[index]; }
}
}
答案 1 :(得分:1)
问题是当你试图返回一个对象的数组时 - 至少它对我而言。
我发现我需要创建一个对象类类型的List,将该列表添加到DataContractSerrializer(typeof(mylist));
由此;
List<LinqtoSQLTableClass> mylist = new List<LinqtoSQLTableClass>();
DataContractSerializer(mylist.GetType());
StringBuilder sb = new StringBuilder();
var query = linqtosql blah blah
XmlWriter writer = XmlWriter.Create(sb);
dcs.WriteObject(writer, query);
writer.Close();
答案 2 :(得分:-1)
以下是我用于克隆或序列化对象的一些代码。我很想知道你是否有同样的问题。此代码只返回一个Object类型,但您可以将结果强制转换为对象类型。
var serializer = new System.Runtime.Serialization.DataContractSerializer(GetType());
using (var ms = new System.IO.MemoryStream())
{
serializer.WriteObject(ms, this);
ms.Position = 0;
return serializer.ReadObject(ms);
}