2010-09-02 80 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

相關問題