0

观察以下示例代码:

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;
}
4

3 回答 3

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]; }
    }
}
于 2009-12-01T20:48:38.680 回答
1

问题是当你试图返回一个对象数组时——至少对我来说是这样。

我发现我需要创建一个对象类类型的列表,将该列表添加到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();
于 2010-02-16T22:50:03.667 回答
-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);
}
于 2009-12-01T20:23:08.910 回答