实现IList外观,但GetEnumerator返回0

时间:2012-08-22 12:27:55

标签: c#

我对.NET中的编程有点新意,而且有一些问题让我感到困惑。

我正在尝试在我的一个类中实现IList<T>接口。我想暂时保持简单,所以我只是为方法使用声明的List<T>字段的功能,并在其间添加了一些自定义数据处理。

大多数方法都运行良好,字段列表会按预期添加。但是,当我尝试将该类用作列表(例如class.ForEach())时,它返回Count为0.这是尽管内部List<T>计数为25。

我确信这很简单,如果这个问题浪费了数据库空间,我很抱歉,但这真的让我感到很震惊。你们中的任何人可以帮我解决吗?

我会发布我当前的代码来展示我正在尝试做的事情:

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<T> : IDataRepository<T> where T : ClubEventData, new()
    {
        private readonly PropertyDictionaryBasedDynamicConverter<T> _converter;
        private readonly IDataHandler _dataHandler;
        private readonly List<T> _storageList;

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

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

        #region Implementation of IEnumerable

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

        #endregion

        #region Implementation of ICollection<T>

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

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

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

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

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

        /// <summary>
        /// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </summary>
        /// <returns>
        /// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
        /// </returns>
        /// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
        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);
        }

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

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

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

        ///<summary>Creates the data item in the database and returns the model version of it.</summary>
        private T CreateDataItem(T item)
        {
            // Get the properties of the item.
            Dictionary<string, object> 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;
        }

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

            // 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 && mappingAttribute.MappingEnabled)
                {
                    string mappingValue = mappingAttribute.MappingName != null && 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;
        }

        /// <summary>
        /// Performs validation operations on the item.
        /// </summary>
        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<T>

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

        /// <summary>
        /// Inserts an item to the <see cref="T:System.Collections.Generic.IList`1"/> at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param><param name="item">The object to insert into the <see cref="T:System.Collections.Generic.IList`1"/>.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
        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);
        }

        /// <summary>
        /// Removes the <see cref="T:System.Collections.Generic.IList`1"/> item at the specified index.
        /// </summary>
        /// <param name="index">The zero-based index of the item to remove.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
        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);
        }

        /// <summary>
        /// Gets or sets the element at the specified index.
        /// </summary>
        /// <returns>
        /// The element at the specified index.
        /// </returns>
        /// <param name="index">The zero-based index of the element to get or set.</param><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is not a valid index in the <see cref="T:System.Collections.Generic.IList`1"/>.</exception><exception cref="T:System.NotSupportedException">The property is set and the <see cref="T:System.Collections.Generic.IList`1"/> is read-only.</exception>
        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

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

        #endregion
    }
}

这是我用来调用存储库的方法:

using System.Collections.Generic;
using ClubEventsData;
using System.Linq;
using System;

namespace ClubEventsDataHandling.System.Implementations.Controllers
{
    public class TicketDataController : IDataController
    {
        private DataRepository<Ticket> _repository;

        public TicketDataController()
        {
            _repository = new DataRepository<Ticket>();
        }

        public List<Ticket> GetDateTickets(Guid dateID)
        {
            return _repository.Where(ticket => ticket.EventDateBoughtFor.MasterContentID == dateID).ToList();
        }
    }
}

1 个答案:

答案 0 :(得分:2)

_repository.Count为0的原因只是您没有访问_storageList媒体资源中的Count。您需要将其更改为:

public int Count
{ 
    get { return _storageList.Count; }
} 
相关问题