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 theyield break;
earlier (and change it toreturn list.GetEnumerator();
). If you want to keep your code as an iterator block, you should be usingyield return
to yield each node you create. - You should be yielding instances of
T
- whereas you're constructing instances ofProductNode
. Perhaps you should actually be implementingIEnumerable<ProductNode>
instead ofIEnumerable<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 yournodeReader
is disposed on error (assuming the caller disposes of theIEnumerator<T>
of course) - Your public
list
field is a bad idea... why have you made it an instance variable at all?
精彩评论