How to make XML Serialization play nicely with C# indexers (this[])?
How can I XML-serialize the following property:
publ开发者_StackOverflow中文版ic class SomeCollection
{
[Xml???]
public SomeClass this[int i]
{
get { ... }
set { ... }
}
}
I have tried using XmlElement
, XmlArray
and XmlArrayItem
, to no avail.
The XmlSerializer
doesn't work on Indexers, you would either have to implement IXmlSerializable
or (better) use a surrogate property to do the heavy lifting for you.
According to Microsoft, indexer can't be serialize with XMLSerializer
http://msdn.microsoft.com/en-us/library/182eeyhh.aspx
Note: XML serialization does not convert methods, indexers, private fields, or read-only properties (except read-only collections).
You can't serialize the indexer property. The best you can do is expose another property (one that's XML-serializable) that ties into the same collection being used by the indexer.
public class SomeCollection
{
[XmlIgnore]
public SomeClass this[int i]
{
get { ... }
set { ... }
}
[XmlArray(ElementName="someClasses")]
[XmlArrayItem(ElementName="someClass", Type=typeof(SomeClass))]
public List<SomeClass> someClasses
{
get
{
// tie this into the same collection access by the indexer...
}
set
{
// tie this into the same collection access by the indexer...
}
}
}
The easiest way is to implement IEnumerable and the appropriate Add method.
For example, if your indexer utilizes List to store your list, the following code should do the job:
Add IEnumerable to the list of interfaces being implemented. Initialize _list and implement your indexer.
private List<SomeClass> _list;
...
public override void Add(SomeClass instance)
{
mInstances.Add(instance);
}
public IEnumerator<T> GetEnumerator()
{
foreach (SomeClass instance in _list)
{
yield return instance;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
See XmlSerializer Class which includes the following note:
The XmlSerializer gives special treatment to classes that implement IEnumerable or ICollection. A class that implements IEnumerable must implement a public Add method that takes a single parameter. The Add method's parameter must be of the same type as is returned from the Current property on the value returned from GetEnumerator, or one of that type's bases. A class that implements ICollection (such as CollectionBase) in addition to IEnumerable must have a public Item indexed property (indexer in C#) that takes an integer, and it must have a public Count property of type integer. The parameter to the Add method must be the same type as is returned from the Item property, or one of that type's bases. For classes that implement ICollection, values to be serialized are retrieved from the indexed Item property, not by calling GetEnumerator.
精彩评论