I don't know why I have Stackoverflow error when Child class call parent class constractor?!
first of all: sorry for my long code, because some of my friends request for it, so I put it for u!
public class XMLCollection<T>: IList<T> where T: new ()
{
private XmlSerializer ser;
private List<T> InnerList= new List<T>();
public XMLCollection()
{
ser = new XmlSerializer(this.GetType(), new XmlRootAttribute(this.GetType().Name ));
}
/// <summary>
///
/// </summary>
/// <param name="path">path format: #"D:\FolderName"</param>
public void SaveToXML(string path)
{
try
{
using (StreamWriter sw = new StreamWriter(path+ "\\"+this.GetType().Name))
{
ser.Serialize(sw, this);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message );
}
}
public void LoadFromXML(string FullPath)
{
try
{
if (File.Exists(FullPath))
{
using (StreamReader sr= new StreamReader(FullPath))
{
this.InnerList=((XMLCollection<T>) ser.Deserialize(sr)).InnerList ;
}
}
else
{
Console.WriteLine("File not exist....");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message );
}
}
#region Ilist
public int IndexOf(T item)
{
throw new NotImplementedException();
}
public void Insert(int index, T item)
{
throw new NotImplementedException();
}
public void RemoveAt(int index)
{
throw new NotImplementedException();
}
public T this[int index]
{
get
{
return InnerList[index];
}
set
{
InnerList[index] = value;
}
}
public void Add(T item)
{
InnerList.Add(item);
}
public void Clear()
{
InnerList.Clear();
}
public bool Contains(T item)
{
throw new NotImplementedException();
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public int Count
{
get { throw new NotImplementedException(); }
}
public bool IsReadOnly
{
get { throw new NotImplementedException(); }
}
public bool Remove(T item)
{
throw new NotImplementedException();
}
public IEnumerator<T> GetEnumerator()
{
return InnerList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return InnerList.GetEnumerator();
}
#endregion
this is derived class:
public class Moshakhase :XMLCollection<Moshakhase>, IDisposable , IComparable<Moshakhase> , IEquatable<Moshakhase>
{
[XmlAttribute]
public int Id { get; set; }
[XmlAttribute]
public string Name { get; set; }
#region ctor
public Moshakhase()
{
}
public Moshakhase(int id, string name)
{
this.Id = id;
this.Name = name;
}
#endregion
public override string ToString()
{
return string.Format("{0}:\tId:{1}\tName:{2}",this.GetType().Name ,this.Id,this.Name);
}
#region dispose
public void Dispose()
{
GC.SuppressFinalize(this);
}
#endregion
#region IComparable
/// <summary>
/// براساس نام
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
public int CompareTo(Moshakhase other)
{
return this.Name.CompareTo(other.Name);
}
#endregion
#region IEquatable
public bool Equals(Moshakhase other)
{
if (this.Id== other.Id)
{
return true;
}
return false;
}
#endregion
}
Thanks for your attention.
I don't know why I removed IList from XMLCollection<T> worked.
maybe because I has implemented IList in an other level of inheritance.
Note: In serializing it's important to implement blank constructor
Related
I have a class that inherits from List<T> and add one more class property
public class DrivenList : List<int>
{
public string Name {get;set;}
private DrivenList() { }
public DrivenList(string name) { this.Nname = name; }
}
When JSON serializing the object using Newtonsoft.Json, I get only the list item. ( [1,2,3] )
Any ideas how to add the Name property to the results?
Solved: by adding this attribute to the list
[JsonObject(MemberSerialization = MemberSerialization.Fields)]
public class DrivenList : List<int>
As far as I know with Newtonsoft all you can do is something like this:
[JsonObject(MemberSerialization = MemberSerialization.Fields)]
public class DrivenList : List<int>
{
[JsonProperty]
public string Name { get; set; }
private DrivenList() { }
public DrivenList(string name) { this.Name = name; }
}
But this will add you unwanted (maybe) fields.
Personally I will do composition instead of inheritance:
public class DrivenList
{
public string Name { get; set; }
public List<int> Items { get; set; }
private DrivenList() { }
public DrivenList(string name) { this.Name = name; }
}
What .NET version are you using and what serializer?
If you are using the standard serializer, then adding [DataMember] annotations would be the answer.
https://msdn.microsoft.com/en-us/library/bb412179(v=vs.110).aspx
But I would suggest to use Json.NET http://www.newtonsoft.com/json
Update:
I would suggest not to directly inherit to List
class Program
{
static void Main(string[] args)
{
var list = new Driven("Ragnarok");
list.Items.Add(1);
list.Items.Add(2);
string json = JsonConvert.SerializeObject(list);
Console.WriteLine(json);
Console.ReadKey();
}
}
public class Driven
{
public Driven(string name)
{
this.Name = name;
}
public List<int> Items { get; set; } = new List<int>();
public string Name { get; set; }
}
Output:
{"Items":[1,2],"Name":"Ragnarok"}
An alternative solution could be to delegate the implementation of IList to your own property. Then you can use the DataContractSerializer. The upside of this is that all the existing C#-code (and all your tests) will still be intact, and no custom logic is needed for serializing it.
If that's not an option and you really want to use NewtonSoft, then you should take a look at this answer, and create your own JsonConverter.
How to serialize/deserialize a custom collection with additional properties using Json.Net
The problem is the following: when an object implements IEnumerable,
JSON.net identifies it as an array of values and serializes it
following the array Json syntax (that does not include properties)
Here's an example that use DataContractSerializer:
JsonHelper from CodeProject
public class JsonHelper
{
/// <summary>
/// JSON Serialization
/// </summary>
public static string JsonSerializer<T>(T t)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream();
ser.WriteObject(ms, t);
string jsonString = Encoding.UTF8.GetString(ms.ToArray());
ms.Close();
return jsonString;
}
/// <summary>
/// JSON Deserialization
/// </summary>
public static T JsonDeserialize<T>(string jsonString)
{
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
T obj = (T)ser.ReadObject(ms);
return obj;
}
}
And the new implementation of your class.
[DataContract]
public class DrivenList : IList<int>
{
[DataMember]
public List<int> Items = new List<int>();
[DataMember]
public string Name { get; set; }
private DrivenList() { }
public DrivenList(string name) { this.Name = name; }
#region Implementation of IList
public IEnumerator<int> GetEnumerator()
{
return Items.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable)Items).GetEnumerator();
}
public void Add(int item)
{
Items.Add(item);
}
public void Clear()
{
Items.Clear();
}
public bool Contains(int item)
{
return Items.Contains(item);
}
public void CopyTo(int[] array, int arrayIndex)
{
Items.CopyTo(array, arrayIndex);
}
public bool Remove(int item)
{
return Items.Remove(item);
}
public int Count
{
get { return Items.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public int IndexOf(int item)
{
return Items.IndexOf(item);
}
public void Insert(int index, int item)
{
Items.Insert(index, item);
}
public void RemoveAt(int index)
{
Items.RemoveAt(index);
}
public int this[int index]
{
get { return Items[index]; }
set { Items[index] = value; }
}
#endregion
}
And an example usage:
var list = new DrivenList("foo");
list.Add(1);
list.Add(3);
list.Add(5);
var json = JsonHelper.JsonSerializer(list);
Output:
{"Items":[1,3,5],"Name":"foo"}
Apply the DataContract attribute for the class and DataMember attribute for the properties.
[DataContract]
public class DrivenList : List<int>
{
[DataMember]
public string Name {get;set;}
private DrivenList() { }
public DrivenList(string name) { this.Nname = name; }
}
Here is the xml
<?xml version="1.0"?>
<TransactionLog>
<RuleViolations>
<error>
<message>error1</message>
<keys>
<key1>val1</key1>
<key2>val2</key2>
<key3>val3</key3>
<key4>val4</key4>
</keys>
</error>
<error>
<message>error1</message>
<keys>
<key1>val5</key1>
<key2>val6</key2>
</keys>
</error>
<error>
<message>error3</message>
<keys>
<key2>val7</key2>
<key3>val8</key3>
<key4>val9</key4>
</keys>
</error>
</RuleViolations>
</TransactionLog>
What I have now:
[XmlRoot("TransactionLog")]
public class TransactionLogModel
{
[XmlArray("RuleViolations")]
[XmlArrayItem("error")]
public List<KeyValuePair<string,string>> RuleViolations { get; set; }
}
But how can we serialize the <keys> section?
The closest SO post I can find is here: Deserialize XML into Dictionary
But I am not using XDocument.
var x = new XmlSerializer(typeof(TransactionLogModel));
var model = (TransactionLogModel)x.Deserialize(new StringReader(log));
How can we deserialize this xml in XmlSerializer?
Firstly, your data model doesn't match your XML -- there are several intermediate classes missing between TransactionLog and keys. Instead, it should look something like:
[XmlRoot("TransactionLog")]
public class TransactionLogModel
{
[XmlElement("RuleViolations")]
public List<RuleViolation> RuleViolations { get; set; }
}
public class RuleViolation
{
public RuleViolation() { this.Errors = new List<Error>(); }
[XmlElement("error")]
public List<Error> Errors { get; set; }
}
public class Error
{
[XmlElement("message")]
public string Message { get; set; }
// To be done.
public List<KeyValuePair<string, string>> Keys { get; set; }
}
Next, to serialize the List<KeyValuePair<string, string>> Keys using the key names as element names, the standard solution is to implement IXmlSerializable on an appropriate type. It's a bit of a nuisance but not awful since your pair values are primitive types (strings) rather that complex types requiring nested serializations.
For instance, you could use the XmlKeyTextValueListWrapper from Serialize Dictionary member to XML elements and data:
public class XmlKeyTextValueListWrapper<TValue> : CollectionWrapper<KeyValuePair<string, TValue>>, IXmlSerializable
{
public XmlKeyTextValueListWrapper() : base(new List<KeyValuePair<string, TValue>>()) { } // For deserialization.
public XmlKeyTextValueListWrapper(ICollection<KeyValuePair<string, TValue>> baseCollection) : base(baseCollection) { }
public XmlKeyTextValueListWrapper(Func<ICollection<KeyValuePair<string, TValue>>> getCollection) : base(getCollection) {}
#region IXmlSerializable Members
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
var converter = TypeDescriptor.GetConverter(typeof(TValue));
XmlKeyValueListHelper.ReadXml(reader, this, converter);
}
public void WriteXml(XmlWriter writer)
{
var converter = TypeDescriptor.GetConverter(typeof(TValue));
XmlKeyValueListHelper.WriteXml(writer, this, converter);
}
#endregion
}
public static class XmlKeyValueListHelper
{
public static void WriteXml<T>(XmlWriter writer, ICollection<KeyValuePair<string, T>> collection, TypeConverter typeConverter)
{
foreach (var pair in collection)
{
writer.WriteStartElement(XmlConvert.EncodeName(pair.Key));
writer.WriteValue(typeConverter.ConvertToInvariantString(pair.Value));
writer.WriteEndElement();
}
}
public static void ReadXml<T>(XmlReader reader, ICollection<KeyValuePair<string, T>> collection, TypeConverter typeConverter)
{
if (reader.IsEmptyElement)
{
reader.Read();
return;
}
reader.ReadStartElement(); // Advance to the first sub element of the list element.
while (reader.NodeType == XmlNodeType.Element)
{
var key = XmlConvert.DecodeName(reader.Name);
string value;
if (reader.IsEmptyElement)
{
value = string.Empty;
// Move past the end of item element
reader.Read();
}
else
{
// Read content and move past the end of item element
value = reader.ReadElementContentAsString();
}
collection.Add(new KeyValuePair<string,T>(key, (T)typeConverter.ConvertFromInvariantString(value)));
}
// Move past the end of the list element
reader.ReadEndElement();
}
public static void CopyTo<TValue>(this XmlKeyTextValueListWrapper<TValue> collection, ICollection<KeyValuePair<string, TValue>> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
if (collection == null)
dictionary.Clear();
else
{
if (collection.IsWrapperFor(dictionary)) // For efficiency
return;
var pairs = collection.ToList();
dictionary.Clear();
foreach (var item in pairs)
dictionary.Add(item);
}
}
}
public class CollectionWrapper<T> : ICollection<T>
{
readonly Func<ICollection<T>> getCollection;
public CollectionWrapper(ICollection<T> baseCollection)
{
if (baseCollection == null)
throw new ArgumentNullException();
this.getCollection = () => baseCollection;
}
public CollectionWrapper(Func<ICollection<T>> getCollection)
{
if (getCollection == null)
throw new ArgumentNullException();
this.getCollection = getCollection;
}
public bool IsWrapperFor(ICollection<T> other)
{
if (other == Collection)
return true;
var otherWrapper = other as CollectionWrapper<T>;
return otherWrapper != null && otherWrapper.IsWrapperFor(Collection);
}
ICollection<T> Collection { get { return getCollection(); } }
#region ICollection<T> Members
public void Add(T item)
{
Collection.Add(item);
}
public void Clear()
{
Collection.Clear();
}
public bool Contains(T item)
{
return Collection.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
Collection.CopyTo(array, arrayIndex);
}
public int Count
{
get { return Collection.Count; }
}
public bool IsReadOnly
{
get { return Collection.IsReadOnly; }
}
public bool Remove(T item)
{
return Collection.Remove(item);
}
#endregion
#region IEnumerable<T> Members
public IEnumerator<T> GetEnumerator()
{
return Collection.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
Then use it like:
public class Error
{
[XmlElement("message")]
public string Message { get; set; }
List<KeyValuePair<string, string>> keys;
[XmlIgnore]
public List<KeyValuePair<string, string>> Keys
{
get
{
// Ensure keys is never null.
return (keys = keys ?? new List<KeyValuePair<string, string>>());
}
set
{
keys = value;
}
}
[XmlElement("keys")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public XmlKeyTextValueListWrapper<string> XmlKeys
{
get
{
return new XmlKeyTextValueListWrapper<string>(() => this.Keys);
}
set
{
value.CopyTo(Keys);
}
}
}
Incidentally, the same solution will work with a public Dictionary<string, string> Keys property, just be sure that the dictionary is pre-allocated:
public class Error
{
[XmlElement("message")]
public string Message { get; set; }
Dictionary<string, string> keys;
[XmlIgnore]
public Dictionary<string, string> Keys
{
get
{
// Ensure keys is never null.
return (keys = keys ?? new Dictionary<string, string>());
}
set
{
keys = value;
}
}
[XmlElement("keys")]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never), DebuggerBrowsable(DebuggerBrowsableState.Never)]
public XmlKeyTextValueListWrapper<string> XmlKeys
{
get
{
return new XmlKeyTextValueListWrapper<string>(() => this.Keys);
}
set
{
value.CopyTo(Keys);
}
}
}
I have implemented a generic custom collection class which only takes a Person type object.
While providing support for the Enumerator to iterate through the collection it shows an error
Cannot apply indexing with [] to an expression of type 'CustomCollection.CustomCollection'
Below is the code snippet for the class I created.
public class CustomCollection<T> : ICollection<T> where T : Person
{
private IList<T> lst = null;
public CustomCollection()
{
lst = new List<T>();
}
public void Add(T item)
{
this.lst.Add(item);
}
public void Clear()
{
this.lst.Clear();
}
public bool Contains(T item)
{
bool result = false;
foreach (T obj in this.lst)
{
if (obj.Id.Equals(item.Id))
{
result = true;
break;
}
}
return result;
}
public void CopyTo(T[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public int Count
{
get { return this.lst.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(T item)
{
bool result = false;
foreach (T obj in this.lst)
{
if (obj.Id.Equals(item.Id))
{
this.lst.Remove(item);
}
}
return result;
}
public IEnumerator<T> GetEnumerator()
{
return new PersonEnumerator<T>(this);
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
The Enumerator class as below:
public class PersonEnumerator<T> : IEnumerator<T> where T : Person
{
private CustomCollection<T> collection = null;
private int index;
private T current;
public PersonEnumerator(CustomCollection<T> collection)
{
this.collection = collection;
this.index = -1;
current = default(T);
}
public T Current
{
get { return this.current; }
}
public void Dispose()
{
throw new NotImplementedException();
}
object IEnumerator.Current
{
get { return this.Current; }
}
public bool MoveNext()
{
if (++this.index >= collection.Count)
{
return false;
}
else
{
this.current = collection[this.index];
}
return true;
}
public void Reset()
{
this.index = -1;
current = default(T);
}
}
Person Class only contains FirstName, LastName & Id as properties in it.
ICollection doesn't implements an indexer. If you want to use indexing, you should implement IList instead.
You can use Linq with ICollection:
var result = Items.ElementAt(index);
Or you can add your own indexer:
public T this[int i]
{
return Items[i];
}
To make your code build, you need to add an indexer, to your CustomCollection<T> class, e.g.
public T this[int index]
{
return lst [index];
}
Then you can say use collection[n] to get the nth element in the MoveNext() method.
Or
Instead of having your PersonEnumerator<T> class you could just expose lst.GetEnumerator() which returns an IEnumerator<T>, i.e.
public IEnumerator<T> GetEnumerator()
{
return lst.GetEnumerator();
}
Unless you're planning on doing anything fancy with your enumerator, you might as well use the one for lst.
as this link , I have public property although this error There was an error generating the XML document occur at ser.Serialize(sw, this); in SaveToXML method.
I have this class as parent, it has one property too!
public class XMLCollection<T> where T: new ()
{
private XmlSerializer ser;
private List<T> m_InnerList= new List<T>();
public List<T> InnerList {
get
{ return m_InnerList; }
set
{ m_InnerList = value; }
}
public XMLCollection()
{
ser = new XmlSerializer(this.GetType(), new XmlRootAttribute(this.GetType().Name ));
}
/// <summary>
///
/// </summary>
/// <param name="path">path format: #"D:\FolderName"</param>
public void SaveToXML(string path)
{
try
{
using (StreamWriter sw = new StreamWriter(path+ "\\"+this.GetType().Name+".xml"))
{
ser.Serialize(sw, this);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message );
}
}
public void LoadFromXML(string FullPath)
{
try
{
if (File.Exists(FullPath))
{
using (StreamReader sr= new StreamReader(FullPath))
{
this.InnerList=((XMLCollection<T>) ser.Deserialize(sr)).InnerList ;
}
}
else
{
Console.WriteLine("File not exist....");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message );
}
}
}
CollectionList is derived from it:
public class CollectionList :XMLCollection<Moshakhase>, IList<Moshakhase>, IDisposable
{
public enum SortType
{
Name, ID
}
#region ctor
public CollectionList()
{
}
public CollectionList(Moshakhase item)
{
this.Add(item);
}
public CollectionList(params Moshakhase[] item)
{
InnerList.AddRange(item);
}
#endregion
public override string ToString()
{
string str = this.GetType().Name + ":\r\n";
foreach (Moshakhase item in this)
{
str += string.Format("\t{0}({1})\r\n", item.Name, item.Id);
}
return str;
}
#region Sort
public void sort(SortType type)
{
switch (type)
{
case SortType.Name:
InnerList.Sort();
break;
case SortType.ID:
InnerList.Sort(new IDCompare());
break;
default:
break;
}
}
class IDCompare : IComparer<Moshakhase>
{
public int Compare(Moshakhase x, Moshakhase y)
{
if (x.Id > y.Id)
{
return 1;
}
else if (x.Id < y.Id)
{
return -1;
}
return 0;
}
}
#endregion
#region Ilist
public int IndexOf(Moshakhase item)
{
return InnerList.IndexOf(item);
}
public void Insert(int index, Moshakhase item)
{
InnerList.Insert(index, item);
}
public void RemoveAt(int index)
{
InnerList.RemoveAt(index);
}
public Moshakhase this[int index]
{
get
{
return InnerList[index];
}
set
{
InnerList[index] = value;
}
}
public void Add(Moshakhase item)
{
InnerList.Add(item);
}
public void Clear()
{
InnerList.Clear();
}
public bool Contains(Moshakhase item)
{
return InnerList.Contains(item);
}
public void CopyTo(Moshakhase[] array, int arrayIndex)
{
InnerList.CopyTo(array,arrayIndex );
}
public int Count
{
get { return InnerList.Count ; }
}
public bool IsReadOnly
{
get { throw new NotImplementedException(); }
}
public bool Remove(Moshakhase item)
{
return InnerList.Remove(item);
}
public IEnumerator<Moshakhase> GetEnumerator()
{
return InnerList.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return InnerList.GetEnumerator();
}
#endregion
public void Dispose()
{
GC.SuppressFinalize(this);
}
}
Users is derived from CollectionList :
public class Users : CollectionList
{
public Users()
{
}
public Users(ketabkhune.unique.User user): base(user)
{
}
public Users(params ketabkhune.unique.User[] user):base(user)
{
}
}
I use this code to check it:
Users uList = new Users(new User[] {new User(4,"Kamran"), new User(3,"Sara"), new User(5,"Bahar") });
uList.SaveToXML(#"F:\xml");
when I combined XMLCollection with CollectionList and define CollectionList as a generic class. that error disappeared..
Don't forget blank constructor
[Serializable()]
public class CollectionList<T> : IList<T>
{
private XmlSerializer ser;
private List<T> InnerList = new List<T>();
#region ctor
public CollectionList()
{
ser = new XmlSerializer(this.GetType());
}
public CollectionList(string CollectionName)
{
ser = new XmlSerializer(this.GetType(), new XmlRootAttribute(CollectionName ));
}
....
Change Your Code Where The Line Like Bellow :
ser.Serialize(sw, m_InnerList);
How to implement IEnumerator on this class so that I can use it in foreach loop.
public class Items
{
private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();
public Configuration this[string element]
{
get
{
if (_items.ContainsKey(element))
{
return _items[element];
}
else
{
return null;
}
}
set
{
_items[element] = value;
}
}
}
In this example Configuration is a simple class with few properties.
Just an example to implement typesafe IEnumerable and not IEnumerator which you will be able to use in foreach loop.
public class Items : IEnumerable<Configuration>
{
private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();
public void Add(string element, Configuration config) {
_items[element] = config;
}
public Configuration this[string element]
{
get
{
if (_items.ContainsKey(element))
{
return _items[element];
}
else
{
return null;
}
}
set
{
_items[element] = value;
}
}
public IEnumerator<Configuration> GetEnumerator()
{
return _items.Values.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _items.Values.GetEnumerator();
}
}
Regards.
You should be able to implement IEnumerator like this:
public class Items : IEnumerator<KeyValuePair<string, Configuration>>
{
private Dictionary<string, Configuration> _items = new Dictionary<string, Configuration>();
public Configuration this[string element]
{
get
{
if (_items.ContainsKey(element))
{
return _items[element];
}
else
{
return null;
}
}
set
{
_items[element] = value;
}
}
int current;
public object Current
{
get { return _items.ElementAt(current); }
}
public bool MoveNext()
{
if (_items.Count == 0 || _items.Count <= current)
{
return false;
}
return true;
}
public void Reset()
{
current = 0;
}
public IEnumerator GetEnumerator()
{
return _items.GetEnumerator();
}
KeyValuePair<string, Configuration> IEnumerator<KeyValuePair<string, Configuration>>.Current
{
get { return _items.ElementAt(current); }
}
public void Dispose()
{
//Dispose here
}
}
But as already noted you could also just implement IEnumerable.
You don't need to implement IEnumerable or any interface. In order to be able to use your class in a foreach, all that you need is to add an instance method to your class with the follwing signature:
IEnumerator GetEnumerator()