开发者

Dont understand IEnumerable<T>

I'm having alot of trouble with my code. When I compile I get the following error:


'Ecommerce.DataHelpers.ProductNodeLoader' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'. 'Ecommerce.DataHelpers.ProductNodeLoader.GetEnumerator()' cannot implement 'System.Collections.IEnumerable.GetEnumerator()' because it does not have the matching return type of 'System.Collections.IEnumerator'.


Im not sure how to solve this so now I have to ask you guys!

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

    }
}

开发者_如何学运维

I apologize for the bad editing!


You're trying to implement the non-generic IEnumerable type too, as IEnumerable<T> extends it. Fortunately, this is easy:

// Along with the existing using directives
using System.Collections;
...

// In the implementing class
IEnumerator IEnumerable.GetEnumerator()
{
    return GetEnumerator();
}

Note that you have to use explicit interface implementation for at least one of the two GetEnumerator() methods you need to implement, as they have the same signature (same name, no parameters) but different return types. Fortunately, the return value of the generic version is fine to use for the non-generic version, which is why the above pattern is usually used.

EDIT: As Josh correctly notes in the comments, you have other problems too:

  • You shouldn't have a return list; at the end of your code, unless you remove the yield break; earlier (and change it to return list.GetEnumerator();). If you want to keep your code as an iterator block, you should be using yield return to yield each node you create.
  • You should be yielding instances of T - whereas you're constructing instances of ProductNode. Perhaps you should actually be implementing IEnumerable<ProductNode> instead of IEnumerable<T>, and make your class non-generic?
  • Your code will keep the SQL connection open for as long as the caller decides to take iterating over it. That may or may not be a problem - but it's worth bearing in mind.
  • You should use a using statement to make sure that your nodeReader is disposed on error (assuming the caller disposes of the IEnumerator<T> of course)
  • Your public list field is a bad idea... why have you made it an instance variable at all?
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜