}
public object ReadObject (Type type)
+ {
+ return ReadObject (type, null);
+ }
+
+ public object ReadObject (Type type, object instance)
{
if (serialized_object_count ++ == serializer.MaxItemsInObjectGraph)
throw SerializationError (String.Format ("The object graph exceeded the maximum object count '{0}' specified in the serializer", serializer.MaxItemsInObjectGraph));
Type ct = GetCollectionElementType (type);
if (ct != null) {
- return DeserializeGenericCollection (type, ct);
+ return DeserializeGenericCollection (type, ct, instance);
} else {
TypeMap map = GetTypeMap (type);
- return map.Deserialize (this);
+ return map.Deserialize (this, instance);
}
}
else
return idx < 0 ? s : String.Concat (s.Substring (idx + 2), ".", s.Substring (0, idx));
}
- IEnumerable<Type> GetInterfaces2 (Type type)
- {
- if (type.IsInterface)
- yield return type;
- foreach (var t in type.GetInterfaces ())
- yield return t;
- }
-
Type GetCollectionElementType (Type type)
{
if (type.IsArray)
return type.GetElementType ();
- if (type.IsGenericType) {
- // returns T for IEnumerable<T>
- foreach (Type i in GetInterfaces2 (type))
- if (i.IsGenericType && i.GetGenericTypeDefinition ().Equals (typeof (IEnumerable<>)))
- return i.GetGenericArguments () [0];
- }
+
+ var inter = type.GetInterface ("System.Collections.Generic.IEnumerable`1", false);
+ if (inter != null)
+ return inter.GetGenericArguments () [0];
+
if (typeof (IEnumerable).IsAssignableFrom (type))
// return typeof(object) for mere collection.
return typeof (object);
return null;
}
- object DeserializeGenericCollection (Type collectionType, Type elementType)
+ object DeserializeGenericCollection (Type collectionType, Type elementType, object collectionInstance)
{
reader.ReadStartElement ();
object ret;
if (collectionType.IsInterface)
collectionType = typeof (List<>).MakeGenericType (elementType);
if (TypeMap.IsDictionary (collectionType)) {
- object dic = Activator.CreateInstance (collectionType);
- var itemSetter = dic.GetType ().GetProperty ("Item");
- var keyarr = new object [1];
+ if (collectionInstance == null)
+ collectionInstance = Activator.CreateInstance (collectionType);
+
+ var keyType = elementType.IsGenericType ? elementType.GetGenericArguments () [0] : typeof (object);
+ var valueType = elementType.IsGenericType ? elementType.GetGenericArguments () [1] : typeof (object);
+ MethodInfo add = collectionType.GetMethod ("Add", new Type [] { keyType, valueType });
for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
if (!reader.IsStartElement ("item"))
// reading a KeyValuePair in the form of <Key .../><Value .../>
reader.Read ();
reader.MoveToContent ();
- object key = ReadObject (elementType.GetGenericArguments () [0]);
+ object key = ReadObject (keyType);
reader.MoveToContent ();
- object val = ReadObject (elementType.GetGenericArguments () [1]);
+ object val = ReadObject (valueType);
reader.Read ();
- keyarr [0] = key;
- itemSetter.SetValue (dic, val, keyarr);
+ add.Invoke (collectionInstance, new [] { key, val });
}
- ret = dic;
+ ret = collectionInstance;
} else if (typeof (IList).IsAssignableFrom (collectionType)) {
#if NET_2_1
Type listType = collectionType.IsArray ? typeof (List<>).MakeGenericType (elementType) : null;
#else
Type listType = collectionType.IsArray ? typeof (ArrayList) : null;
#endif
- IList c = (IList) Activator.CreateInstance (listType ?? collectionType);
+
+ IList c;
+ if (collectionInstance == null)
+ c = (IList) Activator.CreateInstance (listType ?? collectionType);
+ else
+ c = (IList) collectionInstance;
+
for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
if (!reader.IsStartElement ("item"))
throw SerializationError (String.Format ("Expected element 'item', but found '{0}' in namespace '{1}'", reader.LocalName, reader.NamespaceURI));
ret = collectionType.IsArray ? ((ArrayList) c).ToArray (elementType) : c;
#endif
} else {
- object c = Activator.CreateInstance (collectionType);
- MethodInfo add = collectionType.GetMethod ("Add", new Type [] {elementType});
+ if (collectionInstance == null)
+ collectionInstance = Activator.CreateInstance (collectionType);
+
+ MethodInfo add;
+ if (collectionInstance.GetType ().IsGenericType &&
+ collectionInstance.GetType ().GetGenericTypeDefinition () == typeof (LinkedList<>))
+ add = collectionType.GetMethod ("AddLast", new Type [] { elementType });
+ else
+ add = collectionType.GetMethod ("Add", new Type [] { elementType });
+
if (add == null) {
var icoll = typeof (ICollection<>).MakeGenericType (elementType);
- if (icoll.IsAssignableFrom (c.GetType ()))
+ if (icoll.IsAssignableFrom (collectionInstance.GetType ()))
add = icoll.GetMethod ("Add");
}
+ if (add == null)
+ throw new MissingMethodException (elementType.FullName, "Add");
for (reader.MoveToContent (); reader.NodeType != XmlNodeType.EndElement; reader.MoveToContent ()) {
if (!reader.IsStartElement ("item"))
throw SerializationError (String.Format ("Expected element 'item', but found '{0}' in namespace '{1}'", reader.LocalName, reader.NamespaceURI));
- object elem = ReadObject (elementType);
- add.Invoke (c, new object [] {elem});
+ object element = ReadObject (elementType);
+ add.Invoke (collectionInstance, new object [] { element });
}
- ret = c;
+ ret = collectionInstance;
}
reader.ReadEndElement ();
internal static bool IsDictionary (Type type)
{
- if (type.GetInterface ("System.Collections.IDictionary", false) != null)
+ Type inter;
+ inter = type.GetInterface ("System.Collections.IDictionary", false);
+ if (inter != null
+ && type.GetMethod ("Add", new Type[] { typeof (object), typeof (object) }) != null)
return true;
- if (type.GetInterface ("System.Collections.Generic.IDictionary`2", false) != null)
+
+ inter = type.GetInterface ("System.Collections.Generic.IDictionary`2", false);
+ if (inter != null
+ && type.GetMethod ("Add", new Type[] { inter.GetGenericArguments() [0],
+ inter.GetGenericArguments() [1] }) != null)
return true;
return false;
}
- internal static bool IsCollection (Type type)
+ internal static bool IsEnumerable (Type type)
{
+ if (type.IsGenericType &&
+ type.GetGenericTypeDefinition() == typeof (LinkedList<>))
+ return true;
+
if (IsPrimitiveType (type) || IsDictionary (type))
return false;
- if (type.GetInterface ("System.Collections.IEnumerable", false) != null)
+
+ Type inter;
+ inter = type.GetInterface ("System.Collections.Generic.IReadOnlyCollection`1", false);
+ if (inter != null)
+ return true;
+
+ inter = type.GetInterface ("System.Collections.IEnumerable", false);
+ if (inter != null && type.GetMethod ("Add", new Type[] { typeof (object) }) != null)
+ return true;
+
+ inter = type.GetInterface ("System.Collections.Generic.IEnumerable`1", false);
+ if (inter != null && type.GetMethod ("Add", new Type[] { inter.GetGenericArguments() [0] }) != null)
return true;
return false;
}
continue;
if (pi.GetIndexParameters ().Length > 0)
continue;
- if (IsCollection (pi.PropertyType)) {
+ if (IsEnumerable (pi.PropertyType) || IsDictionary (pi.PropertyType)) {
if (!pi.CanRead)
throw new InvalidDataContractException (String.Format ("Property {0} must have a getter", pi));
}
return Activator.CreateInstance (typeof (Dictionary<,>).MakeGenericType (type.GetGenericArguments ()));
else
return new Hashtable ();
- } else if (TypeMap.IsCollection (type)) {
+ } else if (TypeMap.IsEnumerable (type)) {
if (type.IsGenericType)
return Activator.CreateInstance (typeof (List<>).MakeGenericType (type.GetGenericArguments ()));
else
return FormatterServices.GetUninitializedObject (type);
}
- public virtual object Deserialize (JsonSerializationReader jsr)
+ public virtual object Deserialize (JsonSerializationReader jsr, object o)
{
XmlReader reader = jsr.Reader;
bool isNull = reader.GetAttribute ("type") == "null";
if (mm.Name == reader.LocalName && reader.NamespaceURI == String.Empty) {
if (filled.ContainsKey (mm))
throw new SerializationException (String.Format ("Object content '{0}' for '{1}' already appeared in the reader", reader.LocalName, type));
- mm.SetMemberValue (ret, jsr.ReadObject (mm.Type));
+ mm.SetMemberValue (ret, jsr);
filled [mm] = true;
consumed = true;
break;
public abstract object GetMemberOf (object owner);
- public abstract void SetMemberValue (object owner, object value);
+ public abstract void SetMemberValue (object owner, JsonSerializationReader value);
}
class TypeMapField : TypeMapMember
{
return field.GetValue (owner);
}
-
- public override void SetMemberValue (object owner, object value)
+
+ public override void SetMemberValue (object owner, JsonSerializationReader jsr)
{
- field.SetValue (owner, value);
+ field.SetValue (owner, jsr.ReadObject (this.Type));
}
}
return property.GetValue (owner, null);
}
- public override void SetMemberValue (object owner, object value)
+ public override void SetMemberValue (object owner, JsonSerializationReader jsr)
{
- property.SetValue (owner, value, null);
+ var pSetter = this.property.GetSetMethod (true);
+ if (pSetter != null) {
+ property.SetValue (owner, jsr.ReadObject (this.Type), null);
+
+ } else { // no setter
+ var oldValue = property.GetValue (owner, null);
+ try {
+ jsr.ReadObject (this.Type, oldValue);
+ } catch (MissingMethodException e) {
+ throw new InvalidDataContractException (string.Format ("No set method for property '{0}' "
+ + "in type '{1}'.", this.property.Name, this.property.PropertyType.FullName), e);
+ }
+ }
}
}
}
// Author:
// Atsushi Enomoto <atsushi@ximian.com>
// Ankit Jain <JAnkit@novell.com>
+// Antoine Cailliau <antoinecailliau@gmail.com>
//
// Copyright (C) 2005-2007 Novell, Inc. http://www.novell.com
Assert.AreEqual ("foo/bar/members", entity.MembersRelativeLink.ToString ());
}
+
+ #region Test methods for collection serialization
+
+ [Test]
+ public void TestArrayListSerialization ()
+ {
+ var collection = new ArrayListContainer ();
+ var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}";
+ var expectedItemsCount = 4;
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+
+ stream.Position = 0;
+ collection = (ArrayListContainer) serializer.ReadObject (stream);
+
+ Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestBitArraySerialization ()
+ {
+ var collection = new BitArrayContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ public void TestHashtableSerialization ()
+ {
+ var collection = new HashtableContainer ();
+ var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}";
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestHashtableDeserialization ()
+ {
+ var collection = new HashtableContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ serializer.ReadObject (stream);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestQueueSerialization ()
+ {
+ var collection = new QueueContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ public void TestSortedListSerialization ()
+ {
+ var collection = new SortedListContainer ();
+ var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}";
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestSortedListDeserialization ()
+ {
+ var collection = new SortedListContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ serializer.ReadObject (stream);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestStackSerialization ()
+ {
+ var collection = new StackContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ public void TestEnumerableWithAddSerialization ()
+ {
+ var collection = new EnumerableWithAddContainer ();
+ var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}";
+ var expectedItemsCount = 4;
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+
+ stream.Position = 0;
+ collection = (EnumerableWithAddContainer) serializer.ReadObject (stream);
+
+ Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestEnumerableWithSpecialAddSerialization ()
+ {
+ var collection = new EnumerableWithSpecialAddContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ public void TestHashSetSerialization ()
+ {
+ var collection = new GenericHashSetContainer ();
+ var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}";
+ var expectedItemsCount = 2;
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+
+ stream.Position = 0;
+ collection = (GenericHashSetContainer) serializer.ReadObject (stream);
+
+ Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2");
+ }
+
+ [Test]
+ public void TestLinkedListSerialization ()
+ {
+ var collection = new GenericLinkedListContainer ();
+ var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}";
+ var expectedItemsCount = 4;
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+
+ stream.Position = 0;
+ collection = (GenericLinkedListContainer) serializer.ReadObject (stream);
+
+ Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestGenericQueueSerialization ()
+ {
+ var collection = new GenericQueueContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestGenericStackSerialization ()
+ {
+ var collection = new GenericStackContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ public void TestGenericDictionarySerialization ()
+ {
+ var collection = new GenericDictionaryContainer ();
+ var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}";
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestGenericDictionaryDeserialization ()
+ {
+ var collection = new GenericDictionaryContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ serializer.ReadObject (stream);
+ }
+
+ [Test]
+ public void TestGenericSortedListSerialization ()
+ {
+ var collection = new GenericSortedListContainer ();
+ var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}";
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestGenericSortedListDeserialization ()
+ {
+ var collection = new GenericSortedListContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ serializer.ReadObject (stream);
+ }
+
+ [Test]
+ public void TestGenericSortedDictionarySerialization ()
+ {
+ var collection = new GenericSortedDictionaryContainer ();
+ var expectedOutput = "{\"Items\":[{\"Key\":\"key1\",\"Value\":\"banana\"},{\"Key\":\"key2\",\"Value\":\"apple\"}]}";
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+ }
+
+ [Test]
+ [ExpectedException (typeof (ArgumentException))]
+ public void TestGenericSortedDictionaryDeserialization ()
+ {
+ var collection = new GenericSortedDictionaryContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ serializer.ReadObject (stream);
+ }
+
+ [Test]
+ public void TestGenericEnumerableWithAddSerialization ()
+ {
+ var collection = new GenericEnumerableWithAddContainer ();
+ var expectedOutput = "{\"Items\":[\"banana\",\"apple\"]}";
+ var expectedItemsCount = 4;
+
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+
+ stream.Position = 0;
+ Assert.AreEqual (expectedOutput, new StreamReader (stream).ReadToEnd (), "#1");
+
+ stream.Position = 0;
+ collection = (GenericEnumerableWithAddContainer) serializer.ReadObject (stream);
+
+ Assert.AreEqual (expectedItemsCount, collection.Items.Count, "#2");
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestGenericEnumerableWithSpecialAddSerialization ()
+ {
+ var collection = new GenericEnumerableWithSpecialAddContainer ();
+ var serializer = new DataContractJsonSerializer (collection.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, collection);
+ }
+
+ [Test]
+ [ExpectedException (typeof (InvalidDataContractException))]
+ public void TestNonCollectionGetOnlyProperty ()
+ {
+ var o = new NonCollectionGetOnlyContainer ();
+ var serializer = new DataContractJsonSerializer (o.GetType ());
+ var stream = new MemoryStream ();
+ serializer.WriteObject (stream, o);
+ }
+
+ #endregion
}
public class CharTest
public string GetValue { get { return this.Value; } }
}
+#region Test classes for Collection serialization
+
+[DataContract]
+ public abstract class CollectionContainer <V>
+ {
+ V items;
+
+ [DataMember]
+ public V Items
+ {
+ get {
+ if (items == null) items = Init ();
+ return items;
+ }
+ }
+
+ public CollectionContainer ()
+ {
+ Init ();
+ }
+
+ protected abstract V Init ();
+ }
+
+ [DataContract]
+ public class ArrayListContainer : CollectionContainer<ArrayList> {
+ protected override ArrayList Init ()
+ {
+ return new ArrayList { "banana", "apple" };
+ }
+ }
+
+ [DataContract]
+ public class BitArrayContainer : CollectionContainer<BitArray> {
+ protected override BitArray Init ()
+ {
+ return new BitArray (new [] { false, true });
+ }
+ }
+
+ [DataContract]
+ public class HashtableContainer : CollectionContainer<Hashtable> {
+ protected override Hashtable Init ()
+ {
+ var ht = new Hashtable ();
+ ht.Add ("key1", "banana");
+ ht.Add ("key2", "apple");
+ return ht;
+ }
+ }
+
+ [DataContract]
+ public class QueueContainer : CollectionContainer<Queue> {
+ protected override Queue Init ()
+ {
+ var q = new Queue ();
+ q.Enqueue ("banana");
+ q.Enqueue ("apple");
+ return q;
+ }
+ }
+
+ [DataContract]
+ public class SortedListContainer : CollectionContainer<SortedList> {
+ protected override SortedList Init ()
+ {
+ var l = new SortedList ();
+ l.Add ("key1", "banana");
+ l.Add ("key2", "apple");
+ return l;
+ }
+ }
+
+ [DataContract]
+ public class StackContainer : CollectionContainer<Stack> {
+ protected override Stack Init ()
+ {
+ var s = new Stack ();
+ s.Push ("banana");
+ s.Push ("apple");
+ return s;
+ }
+ }
+
+ public class EnumerableWithAdd : IEnumerable
+ {
+ private ArrayList items;
+
+ public EnumerableWithAdd()
+ {
+ items = new ArrayList();
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return items.GetEnumerator();
+ }
+
+ public void Add(object value)
+ {
+ items.Add(value);
+ }
+
+ public int Count
+ {
+ get {
+ return items.Count;
+ }
+ }
+ }
+
+ public class EnumerableWithSpecialAdd : IEnumerable
+ {
+ private ArrayList items;
+
+ public EnumerableWithSpecialAdd()
+ {
+ items = new ArrayList();
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return items.GetEnumerator();
+ }
+
+ public void Add(object value, int index)
+ {
+ items.Add(value);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return items.Count;
+ }
+ }
+ }
+
+ [DataContract]
+ public class EnumerableWithAddContainer : CollectionContainer<EnumerableWithAdd>
+ {
+ protected override EnumerableWithAdd Init()
+ {
+ var s = new EnumerableWithAdd();
+ s.Add ("banana");
+ s.Add ("apple");
+ return s;
+ }
+ }
+
+ [DataContract]
+ public class EnumerableWithSpecialAddContainer : CollectionContainer<EnumerableWithSpecialAdd>
+ {
+ protected override EnumerableWithSpecialAdd Init()
+ {
+ var s = new EnumerableWithSpecialAdd();
+ s.Add("banana", 0);
+ s.Add("apple", 0);
+ return s;
+ }
+ }
+
+ [DataContract]
+ public class GenericDictionaryContainer : CollectionContainer<Dictionary<string, string>> {
+ protected override Dictionary<string, string> Init ()
+ {
+ var d = new Dictionary<string, string> ();
+ d.Add ("key1", "banana");
+ d.Add ("key2", "apple");
+ return d;
+ }
+ }
+
+ [DataContract]
+ public class GenericHashSetContainer : CollectionContainer<HashSet<string>> {
+ protected override HashSet<string> Init ()
+ {
+ return new HashSet<string> { "banana", "apple" };
+ }
+ }
+
+ [DataContract]
+ public class GenericLinkedListContainer : CollectionContainer<LinkedList<string>> {
+ protected override LinkedList<string> Init ()
+ {
+ var l = new LinkedList<string> ();
+ l.AddFirst ("apple");
+ l.AddFirst ("banana");
+ return l;
+ }
+ }
+
+ [DataContract]
+ public class GenericListContainer : CollectionContainer<List<string>> {
+ protected override List<string> Init ()
+ {
+ return new List<string> { "banana", "apple" };
+ }
+ }
+
+ [DataContract]
+ public class GenericQueueContainer : CollectionContainer<Queue<string>> {
+ protected override Queue<string> Init ()
+ {
+ var q = new Queue<string> ();
+ q.Enqueue ("banana");
+ q.Enqueue ("apple" );
+ return q;
+ }
+ }
+
+ [DataContract]
+ public class GenericSortedDictionaryContainer : CollectionContainer<SortedDictionary<string, string>> {
+ protected override SortedDictionary<string, string> Init ()
+ {
+ var d = new SortedDictionary<string, string> ();
+ d.Add ("key1", "banana");
+ d.Add ("key2", "apple");
+ return d;
+ }
+ }
+
+ [DataContract]
+ public class GenericSortedListContainer : CollectionContainer<SortedList<string, string>> {
+ protected override SortedList<string, string> Init ()
+ {
+ var d = new SortedList<string, string> ();
+ d.Add ("key1", "banana");
+ d.Add ("key2", "apple");
+ return d;
+ }
+ }
+
+ [DataContract]
+ public class GenericStackContainer : CollectionContainer<Stack<string>> {
+ protected override Stack<string> Init ()
+ {
+ var s = new Stack<string> ();
+ s.Push ("banana");
+ s.Push ("apple" );
+ return s;
+ }
+ }
+
+ public class GenericEnumerableWithAdd : IEnumerable<string>
+ {
+ private List<string> items;
+
+ public GenericEnumerableWithAdd()
+ {
+ items = new List<string>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return items.GetEnumerator ();
+ }
+
+ public IEnumerator<string> GetEnumerator()
+ {
+ return items.GetEnumerator ();
+ }
+
+ public void Add(string value)
+ {
+ items.Add(value);
+ }
+
+ public int Count
+ {
+ get {
+ return items.Count;
+ }
+ }
+ }
+
+ public class GenericEnumerableWithSpecialAdd : IEnumerable<string>
+ {
+ private List<string> items;
+
+ public GenericEnumerableWithSpecialAdd()
+ {
+ items = new List<string>();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return items.GetEnumerator ();
+ }
+
+ public IEnumerator<string> GetEnumerator()
+ {
+ return items.GetEnumerator ();
+ }
+
+ public void Add(string value, int index)
+ {
+ items.Add(value);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return items.Count;
+ }
+ }
+ }
+
+ [DataContract]
+ public class GenericEnumerableWithAddContainer : CollectionContainer<GenericEnumerableWithAdd>
+ {
+ protected override GenericEnumerableWithAdd Init()
+ {
+ var s = new GenericEnumerableWithAdd();
+ s.Add ("banana");
+ s.Add ("apple");
+ return s;
+ }
+ }
+
+ [DataContract]
+ public class GenericEnumerableWithSpecialAddContainer : CollectionContainer<GenericEnumerableWithSpecialAdd>
+ {
+ protected override GenericEnumerableWithSpecialAdd Init()
+ {
+ var s = new GenericEnumerableWithSpecialAdd();
+ s.Add("banana", 0);
+ s.Add("apple", 0);
+ return s;
+ }
+ }
+
+ [DataContract]
+ public class NonCollectionGetOnlyContainer
+ {
+ string _test = "my string";
+
+ [DataMember]
+ public string MyString {
+ get {
+ return _test;
+ }
+ }
+ }
+#endregion
\ No newline at end of file