Implementing IList facade, but GetEnumerator returns a count of 0
<p>I'm a little bit new to programming in .NET, and there's a little bit of a problem that's truly confusing me.</p>

<p>I am trying to implement the <code>IList&lt;T&gt;</code> interface in one of my classes. I wanted to keep things simple for now, so I simply used the functionality of a declared <code>List&lt;T&gt;</code> field for the methods and added some custom data processing in between. </p>

<p>Most of the methods work well, and the field list gets added to as expected. However, when I try to use the class as a list (e.g. <code>class.ForEach()</code>), it returns a <code>Count</code> of 0. This is despite the internal <code>List&lt;T&gt;</code> having a count of 25. </p>

<p>I'm sure this is really simple, and I apologise if this question is a waste of database space, but it's something that's really holding me back. Can any of you guys help me solve it?</p>

<p>I'll post my current code to show what I'm trying to do:</p>

<pre><code>using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reflection;
using ClubEventsData;
using ClubEventsData.Attributes;
using ClubEventsDataHandling.System.Implementations.Conversion;
using Telerik.Sitefinity.DynamicModules.Model;

namespace ClubEventsDataHandling.System.Implementations
{
    public class DataRepository&lt;T&gt; : IDataRepository&lt;T&gt; where T : ClubEventData, new()
    {
        private readonly PropertyDictionaryBasedDynamicConverter&lt;T&gt; _converter;
        private readonly IDataHandler _dataHandler;
        private readonly List&lt;T&gt; _storageList;

        /// &lt;summary&gt;
        /// Initializes a new instance of the DataRepository class.
        /// &lt;/summary&gt;
        public DataRepository()
        {
            _dataHandler = new SitefinityBasedDataHandler&lt;T&gt;();
            _converter = new PropertyDictionaryBasedDynamicConverter&lt;T&gt;();
            _storageList = new List&lt;T&gt;();

            // Populate the data repository.
            foreach (DynamicContent dynamicContent in _dataHandler.Get())
            {
                _storageList.Add(_converter.ConvertToModel(dynamicContent));
            }
        }

        #region Implementation of IEnumerable

        /// &lt;summary&gt;
        /// Returns an enumerator that iterates through the collection.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// A &lt;see cref="T:System.Collections.Generic.IEnumerator`1"/&gt; that can be used to iterate through the collection.
        /// &lt;/returns&gt;
        /// &lt;filterpriority&gt;1&lt;/filterpriority&gt;
        public IEnumerator&lt;T&gt; GetEnumerator()
        {
            return _storageList.GetEnumerator();
        }

        #endregion

        #region Implementation of ICollection&lt;T&gt;

        /// &lt;summary&gt;
        /// Adds an item to the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/summary&gt;
        /// &lt;param name="item"&gt;The object to add to the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.&lt;/param&gt;&lt;exception cref="T:System.NotSupportedException"&gt;The &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is read-only.&lt;/exception&gt;
        public void Add(T item)
        {
            // Create the data item.
            T modelItem = CreateDataItem(item);

            // Add the item to the list.
            _storageList.Add(modelItem);
        }

        /// &lt;summary&gt;
        /// Removes all items from the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/summary&gt;
        /// &lt;exception cref="T:System.NotSupportedException"&gt;The &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is read-only. &lt;/exception&gt;
        public void Clear()
        {
            throw new NotImplementedException();
        }

        /// &lt;summary&gt;
        /// Determines whether the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; contains a specific value.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// true if &lt;paramref name="item"/&gt; is found in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;; otherwise, false.
        /// &lt;/returns&gt;
        /// &lt;param name="item"&gt;The object to locate in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.&lt;/param&gt;
        public bool Contains(T item)
        {
            // Determine if the database contains the item.
            return _dataHandler.Get(item.MasterContentID) != null;
        }

        /// &lt;summary&gt;
        /// Copies the elements of the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; to an &lt;see cref="T:System.Array"/&gt;, starting at a particular &lt;see cref="T:System.Array"/&gt; index.
        /// &lt;/summary&gt;
        /// &lt;param name="array"&gt;The one-dimensional &lt;see cref="T:System.Array"/&gt; that is the destination of the elements copied from &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;. The &lt;see cref="T:System.Array"/&gt; must have zero-based indexing.&lt;/param&gt;&lt;param name="arrayIndex"&gt;The zero-based index in &lt;paramref name="array"/&gt; at which copying begins.&lt;/param&gt;&lt;exception cref="T:System.ArgumentNullException"&gt;&lt;paramref name="array"/&gt; is null.&lt;/exception&gt;&lt;exception cref="T:System.ArgumentOutOfRangeException"&gt;&lt;paramref name="arrayIndex"/&gt; is less than 0.&lt;/exception&gt;&lt;exception cref="T:System.ArgumentException"&gt;The number of elements in the source &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is greater than the available space from &lt;paramref name="arrayIndex"/&gt; to the end of the destination &lt;paramref name="array"/&gt;.&lt;/exception&gt;
        public void CopyTo(T[] array, int arrayIndex)
        {
            _storageList.CopyTo(array, arrayIndex);
        }

        /// &lt;summary&gt;
        /// Removes the first occurrence of a specific object from the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// true if &lt;paramref name="item"/&gt; was successfully removed from the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;; otherwise, false. This method also returns false if &lt;paramref name="item"/&gt; is not found in the original &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/returns&gt;
        /// &lt;param name="item"&gt;The object to remove from the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.&lt;/param&gt;&lt;exception cref="T:System.NotSupportedException"&gt;The &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is read-only.&lt;/exception&gt;
        public bool Remove(T item)
        {
            // Determine if the master content ID has been set.
            ValidateItem(item);

            // Delete the item from the database.
            _dataHandler.Delete(item.MasterContentID);

            // Remove the item from the database.
            return _storageList.Remove(item);
        }

        /// &lt;summary&gt;
        /// Gets the number of elements contained in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// The number of elements contained in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.
        /// &lt;/returns&gt;
        public int Count { get; private set; }

        /// &lt;summary&gt;
        /// Gets a value indicating whether the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is read-only.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// true if the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; is read-only; otherwise, false.
        /// &lt;/returns&gt;
        public bool IsReadOnly { get; private set; }

        /// &lt;summary&gt;
        /// Determines whether the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt; contains a specific value.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// true if &lt;paramref name="itemID"/&gt;'s item is found in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;; otherwise, false.
        /// &lt;/returns&gt;
        /// &lt;param name="itemID"&gt;The ID of the object to locate in the &lt;see cref="T:System.Collections.Generic.ICollection`1"/&gt;.&lt;/param&gt;
        public bool Contains(Guid itemID)
        {
            return _dataHandler.Get(itemID) != null;
        }

        ///&lt;summary&gt;Creates the data item in the database and returns the model version of it.&lt;/summary&gt;
        private T CreateDataItem(T item)
        {
            // Get the properties of the item.
            Dictionary&lt;string, object&gt; propertyDictionary = GetItemProperties(item);

            // Create the data representation of the item.
            Guid createdItemID = _dataHandler.Create(propertyDictionary);

            // Convert a new model item from the dynamic content.
            DynamicContent dynamicContent = _dataHandler.Get(createdItemID);
            T modelItem = _converter.ConvertToModel(dynamicContent);
            return modelItem;
        }

        ///&lt;summary&gt;Gets the properties of the item as a dictionary that is ready to input into data handler methods.&lt;/summary&gt;
        private static Dictionary&lt;string, object&gt; GetItemProperties(T item)
        {
            var propertyDictionary = new Dictionary&lt;string, object&gt;();

            // Filter  the properties according to the mapping attribute.
            foreach (PropertyInfo property in item.GetType().GetProperties())
            {
                // Get the mapping attribute.
                object[] customMappingAttributes = property.GetCustomAttributes(typeof (ClubEventDataMappingAttribute), true);
                var mappingAttribute = customMappingAttributes[0] as ClubEventDataMappingAttribute;

                // Apply the action, depending on the mapping attribute.
                if (mappingAttribute != null &amp;&amp; mappingAttribute.MappingEnabled)
                {
                    string mappingValue = mappingAttribute.MappingName != null &amp;&amp; string.IsNullOrEmpty(mappingAttribute.MappingName) ? property.Name : mappingAttribute.MappingName;
                    if (mappingValue != null)
                    {
                        propertyDictionary.Add(mappingValue, property.GetValue(item, null));
                    }
                }

                // Old code, in case didn't work.
                /*if ()
                {
                    propertyDictionary.Add(property.Name, property.GetValue(item, null));
                }*/
            }

            return propertyDictionary;
        }

        /// &lt;summary&gt;
        /// Performs validation operations on the item.
        /// &lt;/summary&gt;
        private static void ValidateItem(T item)
        {
            // Check that the ID is present on the item.
            if (item.MasterContentID == Guid.Empty)
            {
                throw new ContentIDNotSetException("The master content ID was not set for this exception.");
            }
        }

        #endregion

        #region Implementation of IList&lt;T&gt;

        /// &lt;summary&gt;
        /// Determines the index of a specific item in the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// The index of &lt;paramref name="item"/&gt; if found in the list; otherwise, -1.
        /// &lt;/returns&gt;
        /// &lt;param name="item"&gt;The object to locate in the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.&lt;/param&gt;
        public int IndexOf(T item)
        {
            return _storageList.IndexOf(item);
        }

        /// &lt;summary&gt;
        /// Inserts an item to the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt; at the specified index.
        /// &lt;/summary&gt;
        /// &lt;param name="index"&gt;The zero-based index at which &lt;paramref name="item"/&gt; should be inserted.&lt;/param&gt;&lt;param name="item"&gt;The object to insert into the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.&lt;/param&gt;&lt;exception cref="T:System.ArgumentOutOfRangeException"&gt;&lt;paramref name="index"/&gt; is not a valid index in the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.&lt;/exception&gt;&lt;exception cref="T:System.NotSupportedException"&gt;The &lt;see cref="T:System.Collections.Generic.IList`1"/&gt; is read-only.&lt;/exception&gt;
        public void Insert(int index, T item)
        {
            // Create a new data item based off the properties of this one.
            T modelItem = CreateDataItem(item);

            // Insert the model item into the list.
            _storageList.Insert(index, modelItem);
        }

        /// &lt;summary&gt;
        /// Removes the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt; item at the specified index.
        /// &lt;/summary&gt;
        /// &lt;param name="index"&gt;The zero-based index of the item to remove.&lt;/param&gt;&lt;exception cref="T:System.ArgumentOutOfRangeException"&gt;&lt;paramref name="index"/&gt; is not a valid index in the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.&lt;/exception&gt;&lt;exception cref="T:System.NotSupportedException"&gt;The &lt;see cref="T:System.Collections.Generic.IList`1"/&gt; is read-only.&lt;/exception&gt;
        public void RemoveAt(int index)
        {
            // Get the item at the index.
            T item = this[index];

            // Validate the item ID.
            ValidateItem(item);

            // Delete the item from the database.
            _dataHandler.Delete(item.MasterContentID);

            // Remove the item from the list.
            _storageList.RemoveAt(index);
        }

        /// &lt;summary&gt;
        /// Gets or sets the element at the specified index.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// The element at the specified index.
        /// &lt;/returns&gt;
        /// &lt;param name="index"&gt;The zero-based index of the element to get or set.&lt;/param&gt;&lt;exception cref="T:System.ArgumentOutOfRangeException"&gt;&lt;paramref name="index"/&gt; is not a valid index in the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt;.&lt;/exception&gt;&lt;exception cref="T:System.NotSupportedException"&gt;The property is set and the &lt;see cref="T:System.Collections.Generic.IList`1"/&gt; is read-only.&lt;/exception&gt;
        public T this[int index]
        {
            get { return _storageList[index]; }
            set
            {
                // Validate the specified content ID.
                ValidateItem(value);

                // Update the database instance with the item properties.
                _dataHandler.Update(value.MasterContentID, GetItemProperties(value));

                // Reflect the changes in the list.
                _storageList[index] = value;
            }
        }

        #endregion

        #region Implementation of IEnumerable

        /// &lt;summary&gt;
        /// Returns an enumerator that iterates through a collection.
        /// &lt;/summary&gt;
        /// &lt;returns&gt;
        /// An &lt;see cref="T:System.Collections.IEnumerator"/&gt; object that can be used to iterate through the collection.
        /// &lt;/returns&gt;
        /// &lt;filterpriority&gt;2&lt;/filterpriority&gt;
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #endregion
    }
}
</code></pre>

<p>And here is the method I use to call the repository:</p>

<pre><code>using System.Collections.Generic;
using ClubEventsData;
using System.Linq;
using System;

namespace ClubEventsDataHandling.System.Implementations.Controllers
{
    public class TicketDataController : IDataController
    {
        private DataRepository&lt;Ticket&gt; _repository;

        public TicketDataController()
        {
            _repository = new DataRepository&lt;Ticket&gt;();
        }

        public List&lt;Ticket&gt; GetDateTickets(Guid dateID)
        {
            return _repository.Where(ticket =&gt; ticket.EventDateBoughtFor.MasterContentID == dateID).ToList();
        }
    }
}
</code></pre>
