我的代码有很多问题。编译时出现以下错误:
“Ecommerce.DataHelpers.ProductNodeLoader”未实现接口(interface)成员“System.Collections.IEnumerable.GetEnumerator()”。 “Ecommerce.DataHelpers.ProductNodeLoader.GetEnumerator()”无法实现“System.Collections.IEnumerable.GetEnumerator()”,因为它没有匹配的“System.Collections.IEnumerator”返回类型。
我不确定如何解决这个问题,所以现在我必须问问你们!
代码:
namespace Ecommerce.DataHelpers
{
public class ProductNodeLoader<T> : IEnumerable<T>
{
private ISqlHelper sqlHelper;
private IRecordsReader nodeReader;
public List<T> list = new List<T>();
// load all products from given company
public IEnumerator<T> GetEnumerator()
{
int companyId = 2;
try
{
sqlHelper = DataLayerHelper.CreateSqlHelper(GlobalSettings.DbDSN);
nodeReader = sqlHelper.ExecuteReader(@"
SELECT * FROM eCommerceNodes WHERE companyId = @companyId)
", sqlHelper.CreateParameter("@companyId", companyId));
}
catch (Exception e)
{
Log.Add(LogTypes.Custom, -1, e.InnerException.ToString());
yield break;
}
if (nodeReader.HasRecords)
{
while(nodeReader.Read())
{
ProductNode node = new ProductNode();
node.id = nodeReader.Get<int>("id");
node.parentId = nodeReader.Get<int>("parentId");
node.companyId = nodeReader.Get<int>("companyId");
node.path = nodeReader.Get<string>("path");
node.sortOrder = nodeReader.Get<string>("sortOrder");
node.text = nodeReader.Get<string>("text");
node.nodeType = nodeReader.Get<int>("nodeType");
list.Add(node);
}
nodeReader.Close();
}
else
{
throw new ApplicationException("No products to load");
}
return list;
}
}
}
对于错误的编辑,我深表歉意!
最佳答案
您正在尝试实现非通用 IEnumerable
也输入 IEnumerable<T>
扩展它。幸运的是,这很容易:
// Along with the existing using directives
using System.Collections;
...
// In the implementing class
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
请注意,您必须使用 explicit interface implementation对于两个 GetEnumerator()
中的至少一个您需要实现的方法,因为它们具有相同的签名(相同的名称,无参数)但返回类型不同。幸运的是,通用版本的返回值可以很好地用于非通用版本,这就是通常使用上述模式的原因。
编辑:正如 Josh 在评论中正确指出的那样,您还有其他问题:
- 你不应该有
return list;
在代码的末尾,除非您删除yield break;
更早(并将其更改为return list.GetEnumerator();
)。如果您想将代码保留为迭代器 block ,您应该使用yield return
产生您创建的每个节点。 - 您应该生成
T
的实例- 而你正在构建ProductNode
的实例.也许您实际上应该实现IEnumerable<ProductNode>
而不是IEnumerable<T>
, 并使您的类(class)非泛型? - 只要调用者决定对其进行迭代,您的代码就会使 SQL 连接保持打开状态。这可能是也可能不是问题 - 但值得牢记。
- 你应该使用
using
声明以确保您的nodeReader
处理错误(假设调用者当然处理了IEnumerator<T>
) - 您的公众号
list
field 是个坏主意……你为什么要把它变成一个实例变量?
关于c# - 不懂 IEnumerable<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3627368/