2010-09-02 45 views
1

我对代码有很多麻烦。我编译时出现以下错误:不懂IEnumerable <T>


“Ecommerce.DataHelpers.ProductNodeLoader”不实现接口成员“System.Collections.IEnumerable.GetEnumerator()”。 'Ecommerce.DataHelpers.ProductNodeLoader.GetEnumerator()'不能实现'System.Collections.IEnumerable.GetEnumerator()',因为它没有匹配的返回类型'System.Collections.IEnumerator'。


林不知道如何解决这个问题,所以现在我不得不问你们!

CODE:

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; 
     } 

    } 
} 

我的坏编辑道歉!

回答

7

您试图实施非泛型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()方法,因为它们具有相同的签名(名称相同,没有参数),但不同的回报类型。幸运的是,通用版本的返回值适用于非通用版本,这就是通常使用上述模式的原因。

编辑:由于乔希在评论正确地指出,你有其他问题太:

  • 你不应该有一个return list;在你的代码的结束,除非你删除早期的yield break;(和更改到return list.GetEnumerator();)。如果要将代码保留为迭代器块,则应该使用yield return生成您创建的每个节点。
  • 您应该产生T的实例 - 而您正在构建ProductNode的实例。也许你应该实际执行IEnumerable<ProductNode>而不是IEnumerable<T>,并让你的类非泛型?
  • 只要调用者决定迭代它,您的代码就会保持SQL连接处于打开状态。这可能是也可能不是问题 - 但值得铭记。
  • 您应该使用using语句,以确保您的nodeReader设置在错误(假设主叫当然IEnumerator<T>的处置)
  • 你的公共list场是一个坏主意......你为什么要使它成为一个实例变量呢?
+2

我不敢试图在这里竞争,但值得注意的是,这不是他*唯一*的问题。在该方法内部有一个不允许的return语句,并且他返回了一个ProductNode的具体实例,其中泛型类型T是预期的。一般来说,他应该做**收益回报**,而不是将项目添加到列表中。 – Josh 2010-09-02 13:18:26

+0

@Josh:编辑添加这些点和其他几个。 – 2010-09-02 13:25:09

+0

谢谢大家的帮助! 我的第一个版本只包含“yield return node”。但在尝试了一切后,我可以想到我有点绝望=) 已经出现了一个新问题是这样的:为什么不能在try子句中使用yield命令? – Marthin 2010-09-02 14:36:40

相关问题