【问题标题】:Why Class instance overwrites another instance为什么类实例覆盖另一个实例
【发布时间】:2012-09-27 02:31:37
【问题描述】:

我有个问题想问你们。

我有一个如下所示的课程:

public class Node
        {
            public int Kova1;               // Kova 1
            public int Kova2;               // Kova 2
            public int Kova3;               // Kova 3

            public int ActionNo;            // Yapılan İşlem

            public Node(int kova1, int kova2, int kova3, int actionNumber)
            {
                Kova1 = kova1;
                Kova2 = kova2;
                Kova3 = kova3;
                ActionNo = actionNumber;
            }

            public Node(int kova1, int kova2, int kova3)
            {
                Kova1 = kova1;
                Kova2 = kova2;
                Kova3 = kova3;
            }

            public Node()
            {
            }

            public Node AnneNode;
        }

还有这些功能:

public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp)
{
    Node cocukState;

    Node temp2 = temp;

    for (int i = 0; i < 12; i++)
    {
        cocukState = YeniStateOlustur(temp, i);

        if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) &&
        ((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3)))
        {
            cocukState.AnneNode = temp;
            Acik.AddFirst(temp);
        }
    }
}

public Node YeniStateOlustur(Node s, int j)
{
    int tempKova1, tempKova2, tempKova3;

    Node yeniCocuk = new Node();

    yeniCocuk = s;
    yeniCocuk.ActionNo = j;

    // Gelen numaraya göre uygulanan işlemin seçimi yapılıyor.
    switch (j)
    {
        case 0:
            {
                yeniCocuk.Kova1 += (3 - yeniCocuk.Kova1);
                yeniCocuk.Kova2 += 0;
                yeniCocuk.Kova3 += 0;
            }
            break;
        case 1:
            {
                yeniCocuk.Kova1 += 0;
                yeniCocuk.Kova2 += (5 - yeniCocuk.Kova2);
                yeniCocuk.Kova3 += 0;
            }
            break;
    }

    return yeniCocuk;
}

在主函数中

            Node temp = new Node();

            while (!(Acik.Count == 0))
            {
                p.CocukNodeOlustur(Acik, Kapali, temp);
                Kapali.AddLast(temp);
            }

所以当我调试我的程序时,我看到每当代码跳转到 YeniStateOlustur() 函数时,程序中的所有 Node 实例都会受到 YeniStateOlustur更改的影响>()。 函数中的实例似乎覆盖了Node类的所有实例

我不明白为什么会这样?

我该如何克服这个问题?

我对这篇长文致以最诚挚的问候和歉意。

【问题讨论】:

  • “我对这篇长文致以最诚挚的问候和歉意” - 你为什么不把它缩短呢?您提供的代码比您需要的多方式 - 一个简短但完整的示例会更容易使用。
  • @JonSkeet 对不起,我不能让它更容易:/
  • 我相信你可以让它变得更简单......我怀疑你只是没有尝试太多。你认为你真的需要所有的代码来演示这个问题吗?您是否尝试过删除无关位,直到它什么都不做但显示出令人困惑的行为?您向我们展示了大约 250 行代码,但没有说明它的目的是什么,只是对实际发生的情况进行了相当模糊的描述。
  • @JonSkeet 我现在正在尝试编辑。谢谢。
  • 好吧,这有点更好 - 现在我注意到你没有使用 YapilanActionBaslangicNodeSonucNode,尽管你似乎在使用 Acik , pKapali 未声明。同样,一个简短但完整的程序(不是三个 sn-ps)会更容易为您提供帮助。

标签: c# class console-application instance overwrite


【解决方案1】:

问题在于所有节点都是同一个实例。您的示例代码仅包含两次“new Node()”,在第二种情况下(在方法 YeniStateOlustur 内),新实例会立即被丢弃。因此,该函数返回传递给它的相同节点:

public Node YeniStateOlustur(Node s, int j)  
{  
    int tempKova1, tempKova2, tempKova3;  

    Node yeniCocuk = new Node();  

    yeniCocuk = s;  

    //...

    return yeniCocuk;    
}    

CocukNodeOlustur方法中,所有节点变量都指向同一个Node:

public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp) 
{ 
    // here, temp == temp
    Node cocukState;
    // now, temp == temp and cocukState is uninitialized.
    Node temp2 = temp; 
    // now, temp == temp, temp2 == temp, and cocukState is uninitialized.

    for (int i = 0; i < 12; i++) 
    { 
        cocukState = YeniStateOlustur(temp, i); 
        // now, temp == temp, temp2 == temp, and cocukState == temp

        if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) && 
        ((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3))) 
        { 
            cocukState.AnneNode = temp; 
            Acik.AddFirst(temp); 
        } 
    } 
} 

您的代码似乎假定 Node 是一个值类型(结构),但它显然是一个引用类型(类)。如果您不确定其中的区别,您应该退后一步,做一些阅读和实验。

一个快速的解决方法可能是将 Node 的声明更改为一个结构,但我不建议这样做。使用结构进行编程可能非常棘手,如果您对结构和类之间的差异的理解不明确,则尤其如此。

【讨论】:

  • 所以我应该写 Node cocukState = new Node(); ?
  • @Un_NatMenDim 你会在哪里写这个?它有什么帮助?只要你打电话给cocukState = YeniStateOlustur(temp, i);,cocukState 就会指向 temp。在调用之前它指向什么,或者它是被初始化还是未初始化都没有关系。
  • 如果我使用结构类型,我不能写“公共节点AnneNode”。这是不允许的。我真的很困惑。
  • @Un_NatMenDim 正确,因为结构不能递归地包含自己的类型。只要坚持上课。
  • @Un_NatMenDim 我不确定我是否已经让自己理解了——我的答案是否足够清楚?
猜你喜欢
  • 2012-04-10
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多