C# 当我通过值传递一个变量并在方法中更改它时,它的反应就像C中通过引用传递一样#

C# 当我通过值传递一个变量并在方法中更改它时,它的反应就像C中通过引用传递一样#,c#,C#,我正在试着解决c#中的水壶问题。当我试图创建一个可能状态树并将它们存储在字典中时。现在我依靠递归方法来完成这项工作。正如您从下面附带的代码中看到的,在我创建一个根节点并将其添加到字典中之后,我“将其作为值传递”,而不是通过引用另一个方法来为其生成子节点。现在,当它到达addToX()method时,在它里面,当它改变作为参数发送的节点时,它本质上改变了字典中的根节点,而不是局部变量,这是我希望发生的,以便进一步进行。请告诉我我做错了什么。由于根节点得到更新,我无法添加新节点,因为有一个条件可以确

我正在试着解决c#中的水壶问题。当我试图创建一个可能状态树并将它们存储在字典中时。现在我依靠递归方法来完成这项工作。正如您从下面附带的代码中看到的,在我创建一个根节点并将其添加到字典中之后,我“将其作为值传递”,而不是通过引用另一个方法来为其生成子节点。现在,当它到达
addToX()
method时,在它里面,当它改变作为参数发送的节点时,它本质上改变了字典中的根节点,而不是局部变量,这是我希望发生的,以便进一步进行。请告诉我我做错了什么。由于根节点得到更新,我无法添加新节点,因为有一个条件可以确保不会添加重复节点,这实际上会导致我的树中只有一个节点。我还尝试在每个对象中实例化新节点,以明确我希望处理的是局部变量,而不是全局变量

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JugPuzzle
{
[Serializable]
public class probableNode
{
    int id, previd;
    List<int> nextid;
    int x, y;
    Boolean fx = false;

    public probableNode()
    { this.nextid = new List<int>(); }

    public probableNode(int id,int previd,int x,int y)
    {
        this.Id = id;
        this.Previd = previd;
        this.X = x;
        this.Y = y;
        this.nextid = new List<int>();
    }

    public int Id { get => id; set => id = value; }
    public int Previd { get => previd; set => previd = value; }
    public List<int> Nextid { get => nextid; set => nextid = value; }
    public int X { get => x; set => x = value; }
    public int Y { get => y; set => y = value; }
    public Boolean Fx { get => fx; set => fx = value; }
}

class Program
{
    //tree
    static Dictionary<int, probableNode> jTree = new Dictionary<int, probableNode>();
    //list of probableNodes
    static Dictionary<int, int> listprobNodes = new Dictionary<int, int>();
    //max capacity , id , goal state
    static int mx = 0, my = 0, id = 0, gx = 0, gy = 0;
    //flag
    static Boolean flag = false;


    //properties
    public static Dictionary<int, probableNode> JTree { get => jTree; set => jTree = value; }
    public static Dictionary<int, int> ListprobNodes { get => listprobNodes; set => listprobNodes = value; }
    public static int Mx { get => mx; set => mx = value; }
    public static int My { get => my; set => my = value; }
    public static int Gx { get => gx; set => gx = value; }
    public static int Gy { get => gy; set => gy = value; }
    public static int Id { get => id; set => id = value; }
    public static bool Flag { get => flag; set => flag = value; }

    static void Main(string[] args)
    {
        Console.WriteLine("Enter jug capacity of x : ");
        Mx = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Enter jug capacity of y : ");
        My = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Enter Goal state for the jugs : ");

        Console.WriteLine("Enter Goal state for jug x : ");
        Gx = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Enter Goal state for jug y : ");
        Gy = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("Please wait while the result is being processed...");

        createTree();

        var nodes = JTree.Values.Where(no => no.X.Equals(Gx) && no.Y.Equals(Gy));
        if(nodes != null)
        {
            var n = nodes.First();
            Console.WriteLine("Goal state exists! : ");
            List<int> goalPath = new List<int>();
            while(n.Id != 0)
            {
                goalPath.Add(n.Id);
                int previd = n.Previd;
                n = JTree[previd];
            }
            goalPath.Add(n.Id);
            goalPath.Reverse();

            foreach (int nid in goalPath)
            {
                Console.WriteLine("("+JTree[nid].X+","+JTree[nid].Y+")->");
            }
            Console.WriteLine("End");
        }
        else
        {
            Console.WriteLine("Goal state doesn't exists!");
        }
        Console.ReadKey();
    }

    public static void createTree()
    {
        probableNode root = new probableNode(id, id, 0, 0);
        JTree.Add(id, root);

        generateChildNodes(root, id);
    }

    public static void generateChildNodes(probableNode node, int pid)
    {
            int x = node.X;
            int y = node.Y;
            int cid = pid;
            probableNode pn = node;
            AddToX(pn, cid);
            pn = node;
            AddToY(node, cid);
            pn = node;
            TransferToX(node, cid);
            pn = node;
            TransferToY(node, cid);
            pn = node;
            EmptyX(node, cid);
            pn = node;
            EmptyY(node, cid);
            JTree[cid].Fx = true;
    }

    public static Boolean checkNode(probableNode node)
    {
        var nodes = JTree.Values.Where(no => no.X.Equals(node.X) && no.Y.Equals(node.Y));
        if (nodes == null)
        { 
            node.Previd = node.Id;
            JTree[id].Nextid.Add(id+1);
            id++;
            node.Id = id;
            JTree.Add(id, node);

            return true;
        }
        else
        {
            var n = nodes.First();
            if(node.Id != n.Id)
            {
                JTree[node.Id].Nextid.Add(n.Id);
            }
            return false;
        }
    }
        public static void AddToX(probableNode node, int pid)
        {
        probableNode newn = new probableNode();
        newn = node;
            if (newn.X < Mx)
            {
                newn.X = Mx;
            }
            Boolean f = checkNode(newn);
            if (f == true)
            {
                generateChildNodes(newn, newn.Id);
            }
        }

        public static void AddToY(probableNode node, int pid)
        {
        probableNode newn = new probableNode();
        newn = node;
        if (newn.Y < My)
        {
            newn.Y = My;
        }
        Boolean f = checkNode(newn);
        if (f == true)
        {
            generateChildNodes(newn, newn.Id);
        }
    }

    public static void TransferToX(probableNode node, int pid)
    {
        probableNode newn = new probableNode();
        newn = node;
        newn.X += newn.Y;
        newn.Y = 0;
        if(newn.X > Mx)
        {
            newn.X = Mx;
        }
        Boolean f = checkNode(newn);
        if (f == true)
        {
            generateChildNodes(newn, newn.Id);
        }

    }

    public static void TransferToY(probableNode node, int pid)
    {
        probableNode newn = new probableNode();
        newn = node;
        newn.Y += newn.X;
        node.X = 0;
        if (newn.Y > My)
        {
            newn.Y = My;
        }
        Boolean f = checkNode(newn);
        if (f == true)
        {
            generateChildNodes(newn, newn.Id);
        }
    }

    public static void EmptyX(probableNode node, int pid)
    {
        probableNode newn = new probableNode();
        newn = node;
        newn.X = 0;
        Boolean f = checkNode(newn);
        if (f == true)
        {
            generateChildNodes(newn, newn.Id);
        }

    }

    public static void EmptyY(probableNode node, int pid)
    {
        probableNode newn = new probableNode();
        newn = node;
        newn.Y = 0;
        Boolean f = checkNode(newn);
        if (f == true)
        {
            generateChildNodes(newn, newn.Id);
        }

    }


}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间难题
{
[可序列化]
公共类概率节点
{
int-id,previd;
列名nextid;
int x,y;
布尔值fx=false;
公共概率节点()
{this.nextid=new List();}
公共概率节点(int-id,int-previd,int-x,int-y)
{
这个.Id=Id;
this.Previd=Previd;
这个.X=X;
这个。Y=Y;
this.nextid=新列表();
}
公共int Id{get=>Id;set=>Id=value;}
public int Previd{get=>Previd;set=>Previd=value;}
公共列表Nextid{get=>Nextid;set=>Nextid=value;}
公共整数X{get=>X;set=>X=value;}
公共整数Y{get=>Y;set=>Y=value;}
公共布尔值Fx{get=>Fx;set=>Fx=value;}
}
班级计划
{
//树
静态字典jTree=新字典();
//概率节点列表
静态字典listprobNodes=新字典();
//最大容量、id、目标状态
静态int mx=0,my=0,id=0,gx=0,gy=0;
//旗
静态布尔标志=false;
//性质
公共静态字典JTree{get=>JTree;set=>JTree=value;}
公共静态字典ListprobNodes{get=>ListprobNodes;set=>ListprobNodes=value;}
公共静态int Mx{get=>Mx;set=>Mx=value;}
公共静态int My{get=>My;set=>My=value;}
公共静态int Gx{get=>Gx;set=>Gx=value;}
公共静态int-Gy{get=>Gy;set=>Gy=value;}
公共静态int-Id{get=>Id;set=>Id=value;}
公共静态bool标志{get=>Flag;set=>Flag=value;}
静态void Main(字符串[]参数)
{
控制台。写入线(“输入x的罐容量:”;
Mx=Convert.ToInt32(Console.ReadLine());
控制台写入线(“输入y的罐容量:”;
My=Convert.ToInt32(Console.ReadLine());
控制台.WriteLine(“输入水壶的目标状态:”);
Console.WriteLine(“输入JugX的目标状态:”);
Gx=Convert.ToInt32(Console.ReadLine());
控制台.WriteLine(“输入jug y的目标状态:”);
Gy=Convert.ToInt32(Console.ReadLine());
WriteLine(“正在处理结果,请稍候…”);
createTree();
var节点=JTree.Values,其中(no=>no.X.Equals(Gx)&&no.Y.Equals(Gy));
如果(节点!=null)
{
var n=nodes.First();
WriteLine(“目标状态存在!:”;
List goalPath=新列表();
而(n.Id!=0)
{
目标路径添加(n.Id);
int previd=n.previd;
n=JTree[previd];
}
目标路径添加(n.Id);
goalPath.Reverse();
foreach(目标路径中的int nid)
{
Console.WriteLine(“(“+JTree[nid].X+”,“+JTree[nid].Y+”->”);
}
控制台。写入线(“结束”);
}
其他的
{
WriteLine(“目标状态不存在!”);
}
Console.ReadKey();
}
公共静态void createTree()
{
概率节点根=新概率节点(id,id,0,0);
JTree.Add(id,root);
generateChildNodes(根,id);
}
公共静态void generateChildNodes(probableNode节点,int pid)
{
int x=node.x;
int y=node.y;
int-cid=pid;
概率节点pn=节点;
AddToX(pn,cid);
pn=节点;
AddToY(节点,cid);
pn=节点;
TransferToX(节点,cid);
pn=节点;
TransferToY(节点,cid);
pn=节点;
EmptyX(节点,cid);
pn=节点;
EmptyY(节点,cid);
JTree[cid].Fx=true;
}
公共静态布尔校验节点(probableNode节点)
{
var nodes=JTree.Values,其中(no=>no.X.Equals(node.X)&&no.Y.Equals(node.Y));
如果(节点==null)
{ 
node.Previd=node.Id;
JTree[id].Nextid.Add(id+1);
id++;
node.Id=Id;
JTree.Add(id,node);
返回true;
}
其他的
{
var n=nodes.First();
if(node.Id!=n.Id)
{
JTree[node.Id].Nextid.Add(n.Id);
}
返回false;
}
}
公共静态void AddToX(probableNode节点,int-pid)
{
probableNode newn=新probableNode();
newn=节点;
如果(新XprobableNode newn = new probableNode();
newn = node;
public static probableNode Clone(probableNode pn)
{
    probableNode newPn = new probableNode();
    newPn.Id = pn.Id;
    newPn.Previd = pn.Previd;
    newPn.Nextid = new List<int>(pn.Nextid);
    newPn.X = pn.X;
    newPn.Y = pn.Y;
    newPn.Fx = pn.Fx;

    return newPn;
}
probableNode newn = probableNode.Clone(node);