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
IEnumerabletype too, asIEnumerable<T>extends it. Fortunately, this is easy: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:
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 returnto yield each node you create.T– whereas you’re constructing instances ofProductNode. Perhaps you should actually be implementingIEnumerable<ProductNode>instead ofIEnumerable<T>, and make your class non-generic?usingstatement to make sure that yournodeReaderis disposed on error (assuming the caller disposes of theIEnumerator<T>of course)listfield is a bad idea… why have you made it an instance variable at all?