문제

I can't get the "foreach" function to work properly. When I select a node in the treeView it should display the sum of the times for each children/grandchildrens (every node contains an integer time variable) pretty much like the usual examples with hierarchy tree over a company and when a boss is selected it should sum up the subordinates salaries. But for some reason it only sum up the childrens times, it only goes one step down in the list of subordinates so to speak.

Hope what I'm trying to achieve is clear, if not please tell me and I'll try to explain it further!

// This is in the Form1 class and is calles when a node is selected in a treeView:
private void getTimeSum(ProductionElement prod)
{

    int sum;

    sum = prod.getSumOfTimes();
    totalTimeLabel.Text = sum.ToString();
}

class CompositeElement : ProductionElement
{
    //The composite class for the composite pattern

    protected List<ProductionElement> subordinates = new List<ProductionElement>();

    public int getSumOfTimes()
    {
         int sum;

         foreach (var prodel in subordinates)
         {
              sum += prodel.getIdealTime();
         }

         return sum;
    }

    public int getIdealTime()
    {
        return idealTime;
    }
}
도움이 되었습니까?

해결책

You need to use recursion -- typically you would only have values at a leaf node in such a case... like this:

public int getSumOfTimes()
{
     int sum;

     if (subordinates.Count() == 0)
     {
       sum =  getIdealTime();
     }
     else
     {
       foreach (var prodel in subordinates)
       {
         sum += prodel.getSumOfTimes();
       }
     }
     return sum;
}

If you have data at a regular node also then you would need to add a call to getIdealTime() after the foreach

다른 팁

If your production element defines a getIdealTime, then your composite element should define a getIdealTime that takes all its children into account. So you would want to put the code for getSumOfTimes into the getIdealTime function instead. That way, other composite elements within your list would automatically go through their own list to calculate their value.

If you don’t want that—although that would be the point about the composite pattern—then you could still fix your implementation to check for other composite elements explicitely:

foreach (var prodel in subordinates)
{
    if (prodel is CompositeElement)
        sum += ((CompositeElement)prodel).getSumOfTimes();
    else
        sum += prodel.getIdealTime();
}

To get the sum do something like:

public int getSumOfTimes(List<ProductionElement> subordinates)
{
     return subordinates.Sum(prodel => prodel.idealTime);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top