我对 .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();
}
}
}