我写了一个通用的List类型。如何使List可序列化?我主要关心的是GetObjectData()
方法。
以下是我的List类及其方法。我之前使用C#中已有的List<>
进行了XML序列化,但我不知道应该在GetObjectData()
方法中写什么。某种形式的foreach
循环可能?
class Liste<T> : IEnumerable, ISerializable
{
List_Element<T> First;
List_Element<T> Last;
int position = -1;
public T this[int index]
{
get
{
return GetAt(index);
}
set
{
//Person p = new Person();
//InsertAt(index, p);
}
}
public bool MoveNext()
{
position++;
if (currentElement == null)
{
currentElement = First;
}
else
{
currentElement = currentElement.Next;
}
return (position < Count);
}
internal bool MovePrev()
{
position--;
if (currentElement == null)
{
currentElement = Last;
}
else
{
currentElement = currentElement.Prev;
}
return currentElement != null;
}
private List_Element<T> currentElement;
public T Current
{
get
{
return currentElement.Data;
}
}
public void Add(T data)
{
List_Element<T> listelement = new List_Element<T>();
listelement.Data = data;
if (First == null)
{
First = listelement;
Last = listelement;
}
else
{
Last.Next = listelement;
listelement.Prev = Last;
Last = listelement;
}
Count++;
}
public int Count { get; private set; }
public void NeueListe()
{
First = null;
}
public void InsertEnd(T data)
{
List_Element<T> ende = new List_Element<T>();
ende.Data = data;
if (First == null)
{
First = ende;
Last = ende;
}
else
{
Last.Next = ende;
ende.Prev = Last.Prev;
Last = ende;
ende.Prev.Prev = Last.Prev.Prev;
}
Count++;
}
public void Reset()
{
position = -1;
}
public T GetAt(int index)
{
List_Element<T> laufvariable;
laufvariable = First;
for (int i = 0; i < index; i++)
{
laufvariable = laufvariable.Next;
}
if (index == 0)
{
return laufvariable.Data;
}
else
{
return laufvariable.Data;
}
}
public void InsertAt(int index, T data)
{
List_Element<T> insertElement = new List_Element<T>();
insertElement.Data = data;
if (index == 0)
{
insertElement.Next = First;
First = insertElement;
}
else
{
List_Element<T> laufVariable;
laufVariable = First;
for (int i = 0; i < index - 1; i++)
{
laufVariable = laufVariable.Next;
}
insertElement.Next = laufVariable.Next;
laufVariable.Next = insertElement;
insertElement.Prev = laufVariable;
}
if (insertElement.Next == null)
{
Last = insertElement;
}
else
{
insertElement.Next.Prev = insertElement;
}
}
public void RemoveAt(int index)
{
if (index == 0)
{
if (Count == 1)
{
First = null;
Last = null;
Count--;
return;
}
//First = First.Next;
//First.Prev = null;
else
{
First = First.Next;
First.Prev = null;
Count--;
}
}
else
{
List_Element<T> laufvariable;
laufvariable = First;
for (int i = 0; i < index - 1; i++)
{
laufvariable = laufvariable.Next;
}
if (laufvariable.Next.Next == null)
{
Last = laufvariable;
laufvariable.Next = null;
}
else
{
laufvariable.Next = laufvariable.Next.Next;
laufvariable.Next.Prev = laufvariable;
}
Count--;
}
}
public void Removelast(int index)
{
List_Element<T> laufvariable;
laufvariable = First;
for (int i = 0; i < index - 1; i++)
{
laufvariable = laufvariable.Next;
}
laufvariable = null;
}
public IEnumerator GetEnumerator()
{
if (First == null)
{
yield break;
}
if (First == Last)
{
yield return First;
MoveNext();
}
MoveNext();
while (currentElement != null)
{
yield return currentElement;
MoveNext();
}
if (currentElement == null)
{
Reset();
yield break;
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// What to do here?
}
答案 0 :(得分:0)
稍微修改一下你的问题,你在问:
我有一个实现
IEnumerable
的自定义通用集合。如何在.Net中将其序列化为XML?
.Net有两个XML序列化程序,XmlSerializer
和DataContractSerializer
。两者都有序列化集合的特殊规则,这些集合记录在以下位置:
尽管这些序列化程序不共享代码库,但它们的规则非常相似:
该类型应实现IEnumerable<T>
以及IEnumerable
,以便序列化程序可以确定预期的元素类型。
该类型必须具有无参数构造函数。
该类型必须具有公共Add(T item)
方法,其单个参数可从通用枚举器的泛型类型T
分配。
对于多种类型IEnumerable<T>
,该类型无法多次实施T
。
XmlSerializer
:类型(和通用项目类型)必须是公开的。
集合项目已序列化而不是集合属性。 XmlSerializer
永远不会序列化集合属性。 DataContractSerializer
仅在集合标有[DataContract]
时序列化集合属性,在这种情况下,属性是序列化而不是项目,而不是项目。
通过遵循这些规则,您可以避免完全实现IXmlSerializable
,这很棘手,容易出现细微的错误。
因此,如果我大大简化Liste<T>
,则两个序列化程序都可以序列化以下实现:
public class Liste<T> : IEnumerable<T>
{
readonly List<T> underlyingList = new List<T>();
public void Add(T item)
{
underlyingList.Add(item);
}
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return underlyingList.GetEnumerator();
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
如果我按如下方式定义List<int>
:
var list = new Liste<int>
{
1, 2, 3, 4,
};
两个序列化程序都将生成以下XML:
<ArrayOfInt>
<int>1</int>
<int>2</int>
<int>3</int>
<int>4</int>
</ArrayOfInt>
XmlSerializer
的示范工作.Net fiddle。
正如评论中所述,ISerializable
甚至没有使用XmlSerializer
。它由DataContractSerializer
支持,如文档here所示 - 但使用上述标准模式进行序列化将更容易。