2011-03-07 54 views
0

我已经写了一个简单的方法,接收一个通用的,我想放入一个ArrayList使用ArrayList.Add()方法。但是我发现,当我去添加一个与ArrayList中的前一个项目具有相同类型的新项目时,这个新项目将覆盖以前项目的各个属性。C#ArrayList.Add()覆盖以前的对象添加

下面是代码,它的基本和相当尴尬,我似乎无法纠正这个覆盖问题。

public class ChromosomeTree<T> 
{ 
    private GeneNode<T> root; 
    private ArrayList children = new ArrayList(); 
    private int depMax; 

    string stemp; 

    public ChromosomeTree() 
    { 
     root = null; 
    } 

    public virtual void Clear() 
    { 
     root = null; 
    } 

    public GeneNode<T> Root 
    { 
     get 
     { 
      return root; 
     } 
     set 
     { 
      root = value; 
     } 
    } 

    public int MaxDepth 
    { 
     get 
     { 
      return depMax; 
     } 
     set 
     { 
      depMax = value; 
     } 
    } 

    public ArrayList Children 
    { 
     get 
     { 
      return children; 
     } 
    } 

    public GeneNode<T> lastChild() 
    { 
     return (GeneNode<T>)this.Children[this.Children.Count - 1]; 
    } 

    public void addFull(GeneNode<T> node) 
    { 
     //check if the chromosome tree has a root if not add the first node as the chromosomes root 

     if (this.Root == null) 
     { 
      this.Root = node; 
      children.Add(node); 
      stemp += " " + node.Value; 
     } 
     else 
     { 
      for (int i = 0; i <= this.Children.Count - 1; i++) 
      { 
       GeneNode<T> parent = (GeneNode<T>)this.Children[i]; 

       //check to ensure maxDepth of chromosome tree is not exceeded 
       if (parent.Depth != this.MaxDepth) 
       { 
        //check to see if the current node stil has room for another node to be added to it 
        if ((parent.Children == null) || (parent.Children[1] == null)) 
        { 
         children.Add(node); 
         parent.Add(node); 

         stemp += " " + node.Value; 

         break; 
        } 
       } 
       else 
       { 
        break; 
       } 
      } 
     } 
    } 

    public override string ToString() 
    { 
     string chromosome = String.Empty; 

     foreach(GeneNode<Gene> gene in this.Children) 
     { 
      chromosome += " " + gene.Value.GeneValue.ToString(); 
     } 

     return chromosome; 
    } 
} 

我很确定它是一个简单的错误,但我看了这么久,我不能看到树木。任何想法将不胜感激。

非常感谢提前。

Luke

这里是利用这个类的代码。

编辑:改写时发生之后,该方法已经执行其逻辑

class SimpleChromosome 
{ 
    Random rand = new Random(); 

    Gene funcGene = new Gene(); 
    Gene termGene = new Gene(); 

    private string sChromosome; 

    private int currentdepth; 

    private string grownChromosome() 
    { 
     return sChromosome; 
    } 

    public ChromosomeTree<Gene> fullChromosome() 
    { 
     ChromosomeTree<Gene> chromosone = new ChromosomeTree<Gene>(); 
     //chromosone.MaxDepth = rand.Next(1, 5); 
     chromosone.MaxDepth = 1; 

     int maxGenes = (int)Math.Pow(2, chromosone.MaxDepth + 1) - 1; 

     for (int i = 0; i <= chromosone.MaxDepth; i++) 
     { 
      int numNodesForLevel = (int)Math.Pow(2, i); 
      int numNodesOnLevel = 0; 

      for (int j = 0; j < numNodesForLevel; j++) 
      { 
       if (currentdepth != chromosone.MaxDepth) 
       { 
        funcGene.GenerateValue(GeneType.Function); 
        GeneNode<Gene> geneNode = new GeneNode<Gene>(funcGene); 
        sChromosome += " " + geneNode.Value; 
        chromosone.addFull(geneNode); 

        numNodesOnLevel++; 
       } 
       else 
       { 
        termGene.GenerateValue(GeneType.Terminal); 
        GeneNode<Gene> geneNode = new GeneNode<Gene>(termGene); 
        sChromosome += " " + geneNode.Value; 
        chromosone.addFull(geneNode); 

        numNodesOnLevel++; 
       } 

       if ((numNodesForLevel == numNodesOnLevel) && (currentdepth != chromosone.MaxDepth)) 
       { 
        currentdepth++; 
       } 
      } 
     } 
     currentdepth = 0; 

     //Console.WriteLine("Before ADD :" + sChromosome); 

     sChromosome = ""; 

     return chromosone; 
    } 
} 
+2

可能有助于张贴您正在使用这个类,其中的代码。我想知道你是否只是一直将相同的实例添加到列表中。 – Nick 2011-03-07 12:42:31

+6

为什么你使用'ArrayList'给定你可以清楚地使用泛型,不感兴趣? – 2011-03-07 12:43:53

+0

您是否想要为每个孩子添加一份参考指南到根目录? – smartcaveman 2011-03-07 12:52:36

回答

1

邮政在其中添加这种类型的新对象添加到您的ArrayList代码调用该方法不。

我的猜测是你对同一个对象使用了两个引用。

请记住,对象是引用类型,因此如果将它们分配给对方,则只分配其引用。例如在下面的代码:

Foo foo1 = new Foo(); 
foo1.x = 1; 
Foo foo2 = new Foo(); 
foo2.x = 2; 

foo2 = foo1; // foo2 now points to the same object as foo1; 
// foo1.x does not get copied into foo2.x. 
// You have also lost your reference to the original foo2 object here and it will be garbage collected. 
foo2.x = 100; 
// since foo2 and foo1 are now pointing to the same object. both foo2.x and foo1.x will be 100 
+0

发布通过泛型到add方法的附加代码。 你认为这是调用'GeneNode geneNode = new GeneNode ();'两次使用不同的实例化值的结果。 – user648132 2011-03-07 13:03:33

0

在这个循环parent == Children[i]Childrenchildren

一个getter你真的要被添加相同的节点childrenparent,这将使同一节点的兄弟parent除了孩子?我不是你真正想要做明确但这似乎错了:

if ((parent.Children == null) || (parent.Children[1] == null)) 
    { 
      children.Add(node); 
      parent.Add(node); 
.. 
    } 

编辑

从您发布的问题可能与你如何创建对象支持的代码:

/* outside the loop */ 
    Gene funcGene = new Gene(); 
    Gene termGene = new Gene(); 

...

/* inside the loop*/ 
    funcGene.GenerateValue(GeneType.Function); 
    GeneNode<Gene> geneNode = new GeneNode<Gene>(funcGene); 
    sChromosome += " " + geneNode.Value; 
    chromosone.addFull(geneNode); 

好像你正在使用其构造函数中的Gene两个实例之一多次创建一个新的GeneNode。假设您的GeneNode正在将其保存为属性值,则每个GeneNode都将引用Gene(以及两个之一,即funcGenetermGene)的同一个实例。我猜这是你的意思,当你说新项目与ArrayList中的以前的项目相同的类型,这个新项目覆盖了以前的项目单个属性。对于同一类型的任何节点中的构造函数分配的Gene属性的任何更改都将引用相同的Gene。即使您正在创建新的GeneNodes,它们也是由相同的Gene构建的。

所以假设GeneNode.Value引用Gene,它正在与构造,只能有两个不同的值返回(对应于两个Gene实例中的一个的电流值)由任何节点在任何给定时间点。

也许您想要移动代码以在循环中创建新的Gene

+0

父在这种情况下不是另一个ArrayList它只是一个不同的对象。条件只是检查父母是否有孩子,或者是否已达到其最大子女数量。父母有效地拥有自己的子女ArrayList,其数量不应超过2个。树的多个孩子可以多于2个。 – user648132 2011-03-07 13:06:22

+0

'parent =(GeneNode )this.Children [i];' - - - 和'Children = {get this.children}' - 所以'children.Add()'创建一个父亲的同胞 – 2011-03-07 13:08:54

+0

我很欣赏你在说什么,但'parent =(GeneNode )this.Children [i]; '从树中获取最后一个添加的节点。 'this.children'仅仅是一个容器,用于添加到它不执行的树和父/子关系的所有节点。所以真正做'children.Add()'只是添加一个新的孩子到我可以直接编入索引的树的子树列表中。它不会严格制造任何事物的兄弟姐妹。 – user648132 2011-03-07 13:38:44

1

对于这种关系,你应该对接口进行编码。例如。

public interface IGeneNode{ 
    //genenode definition including perhaps equality interfaces etc 
} 

如果以上是正确的,那么你可以重载你的Assignment操作符来传递你想传递的值。

这也许对你有用。

C# - Multiple generic types in one list

+0

对不起,我没有看到你的意思。你介意进一步解释一下吗? – user648132 2011-03-07 13:28:35