2014-02-21 99 views
0

我正在创建一个应用程序,需要在其中一个类中使用递归聚合。手头的课程授予“组件”,并且组件可以由存储在列表中的子组件组成。以下代码显示了这一点。实现递归聚合

public class Component { 
//vars for class 
public String componentName; 
public String componentShape; 
public String componentColour; 
public String componentMaterial; 
public int numChildComps; 

//list to store child components of component 
public List<Component> childComponents; 

public Component(string _componentName, string _componentShape, string _componentColour, string _componentMaterial, int _numChildComps) 
{ 
    componentName = _componentName; 
    componentShape = _componentShape; 
    componentColour = _componentColour; 
    componentMaterial = _componentMaterial; 
    numChildComps = _numChildComps; 

    //if component has no child components set list to null 
    if (numChildComps == 0) 
    { 
     //instatiate new list 
     childComponents = new List<Component>(); 
     childComponents = null; 
    } 
    else if(numChildComps != 0)//if not null then create child components for the amount stated above. 
    { 
     childComponents = new List<Component>(); 
     for (int i = 0; i < numChildComps; i++) 
     { 
      Console.WriteLine("Add details for child component " + (i+1)); 
      Console.WriteLine("Enter component Name: "); 
      string name = Console.ReadLine(); 
      Console.WriteLine("Enter shape: "); 
      string shape = Console.ReadLine(); 
      Console.WriteLine("Enter Colour: "); 
      string colour = Console.ReadLine(); 
      Console.WriteLine("Enter Material: "); 
      string material = Console.ReadLine(); 
      Console.WriteLine("Enter num child components: "); 
      string num = Console.ReadLine(); 
      childComponents.Add(new Component(name, shape, colour, material, Int16.Parse(num)));//instatiate new child component with params and add to the list. 
     } 
    } 
} 

这将instaiated一类,如果为FO的子组件数的参数大于0,那么它会创建对象并将其存储在列表中的“childComponents”。这工作正常。我的问题是我将如何去检索列表中的项目。以下面作为一个例子,我有一个是由一个组件模型,但该组件由两个部分组成和那些人有另外2和其中的一个有一个组件:

Model 
-component 
    -childComponent 
    -childComponent 
    -childComponent 
     -childComponent 
    -childComponent 

显然,这可以去永远,我已经尝试创建一段代码,以退役所有的组件和子组件,但它没有工作,因为你需要知道一个模型的组件总数量,然后该组件childComponents等等。我曾尝试(上面的例子并不型号)你上面

IEnumerable<SEModel> modelres = from SEModel sm in database 
            select sm; 
    foreach (SEModel item in modelres) 
    { 
     Console.WriteLine(item.getSetModelName); 
     Console.WriteLine(item.componentList.First().componentName); 
     foreach (SEComponent citem in item.componentList) 
     { 
     Console.WriteLine(citem.childComponents.First().componentName); 
     foreach (SEComponent scitem in citem.childComponents) 
     { 
      Console.WriteLine(scitem.componentName); 
     } 
    } 

像说

代码必须知道组件与childcomponents然后他们childcomponents等量。

+0

请出示使用递归不起作用你的代码。 – Athari

+0

如果知道组件的所有子组件及其子组件等的总数,那么它就可以工作。这是不理想的,因为模型的组件数量对于每个模型都是不同的。 –

回答

2
public IEnumerable<Component> GetComponents() 
{ 
    yield return this; 

    foreach(var childComp in childComponents) 
    { 
     foreach(var comp in childComp.GetComponents()) 
     { 
      yield return comp; 
     } 
    } 
} 

如果你不知道什么yield return是一回事,read this

+0

考虑到OP与递归的斗争,我不认为'yield return'是合适的。 :)但是你的代码确实是最干净的解决方案。 – Athari

+0

嘿,它是递归的! ;) – Moho

+0

+1好的解决方案,只是总结一下yield yield object是什么,它是实现枚举器时用于迭代器方法的上下文关键字。基本上,它有两个用例:'yield return obj;'返回序列中的下一个项目。 'yield break;'停止返回序列元素(如果控制到达迭代器方法体的末尾,这会自动发生)。 – chridam

0

如果您需要检索组件作为平面列表,你可以这样来做:

public List<Component> GetAllComponents(List<Component> components) 
{ 
    var result = new List<Component>(); 
    result.AddRange(components); 

    foreach (var component in components) 
     result.AddRange(GetAllComponents(component.childComponents)); 

    return result; 
} 

var allComponents = GetAllComponents(Model.Components); 

我虽然不是从你的问题肯定正是你想做的事。