foreach statement cannot operate on variables of type Dars does not contain a public definition for 'GetEnumerator'
-
28-06-2021 - |
Question
I have a list Dars
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PantaRei.Components
{
public class Dars
{
public float OpBal { get; set; }
public float PlNeOrRec { get; set; }
public float MiCaCol { get; set; }
public float MiDeCol { get; set; }
public float MiWrOff { get; set; }
public float ClBal { get; set; }
public float Tot
{
get { return OpBal+ PlNeOrRec+ MiCaCol + MiDeCol + MiWrOff; }
}
}
}
I create a new dars
Dars secA1 = new Dars();
And Then I use this bit of code to fill it up
public static void GetData(ref Dars secA1, Ddr ddr, Ddrs ddrs, Type pTypes)
{
Array typesEnum = Enum.GetValues(pTypes);
foreach (Enum types in typesEnum)
{
string pType = StringEnum.GetStringValue(types);
secA1.OpBal = ddrs.Out.Sum(o => o.Amount);
secA1.MiDeCol += ddr.Dil.Where(dil => dil.ProductType == pType && dil.ToBeSold).Sum(dil => dil.Amount);
secA1.PlNeOrRec += ddr.Rec.Where(rec => rec.ToBeSold).Sum(rec => rec.Amount);
GetMiCaCol(ref secA1, ddr, pType);
GetMiWrOff(ref secA1, ddr, pType);
}
}
Now I would like to do something like this
int i = 11;
foreach (float g in secA1)
{
daily.Cells[i, 4] = g;
i++;
}
But I'm getting this error
foreach statement cannot operate on variables of type 'PantaRei.Components.Dars' because 'PantaRei.Components.Dars' does not contain a public definition for 'GetEnumerator'
How do I solve this?
Solution
Just because a class has a collection of properties that happen to be float
s, it doesn't make it a collection. Your code appears to be doing what would be done a lot more appropriately with some sort of data binding. What you are attempting to do can be done by marking Dars
as implementing the IEnumerable
interface, and adding an implementation of the GetEnumerator
method that returns the values for the float properties in your class, but I would never condone this approach in a code review. That being said, try this (if you must):
public class Dars : IEnumerable
{
public float OpBal { get; set; }
public float PlNeOrRec { get; set; }
public float MiCaCol { get; set; }
public float MiDeCol { get; set; }
public float MiWrOff { get; set; }
public float ClBal { get; set; }
public float Tot
{
get { return OpBal + PlNeOrRec + MiCaCol + MiDeCol + MiWrOff; }
}
public IEnumerator GetEnumerator()
{
yield return this.OpBal;
yield return this.PlNeOrRec;
yield return this.MiCaCol;
yield return this.MiDeCol;
yield return this.MiWrOff;
yield return this.ClBal;
yield return this.Tot;
}
}
OTHER TIPS
It's not entirely clear what you're trying to do, but you might want to just implement a method returning an IEnumerable<float>
using an iterator block:
public class Dars
{
public float OpBal { get; set; }
public float PlNeOrRec { get; set; }
public float MiCaCol { get; set; }
public float MiDeCol { get; set; }
public float MiWrOff { get; set; }
public float ClBal { get; set; }
public IEnumerable<float> GetValues()
{
yield return OpBal;
yield return PlNeOrRec;
yield return MiCaCol;
yield return MiDeCol;
yield return MiWrOff;
yield return ClBal;
}
public float Tot
{
get { return OpBal+ PlNeOrRec+ MiCaCol + MiDeCol + MiWrOff; }
}
}
... or you could create a List<float>
or a float[]
and return that from the method instead:
public IEnumerable<float> GetValues()
{
return new[] { OpBal, PlNeOrRec, MiCaCol, MiDeCol, MiWrOff, ClBal };
}
Of course, you should adjust the order if that's not what you want.
(As an aside, those are pretty ghastly property names. Are they really what your code exposes?)