C# 将节点添加到链接列表似乎使用了引用。我如何避免这种情况?
编辑: 这是我试图解决的问题的一个更好的例子C# 将节点添加到链接列表似乎使用了引用。我如何避免这种情况?,c#,reference,C#,Reference,编辑: 这是我试图解决的问题的一个更好的例子 var aNode = new Node<string>("please don't change"); var copiedNode = aNode; copiedNode.value = "Hah! Changed."; Console.WriteLine(aNode.value); var阳极=新节点(“请不要更改”); var copiedNode=阳极; copiedNode.value=“哈!已更改。”; 控制台写入线(阳极
var aNode = new Node<string>("please don't change");
var copiedNode = aNode;
copiedNode.value = "Hah! Changed.";
Console.WriteLine(aNode.value);
var阳极=新节点(“请不要更改”);
var copiedNode=阳极;
copiedNode.value=“哈!已更改。”;
控制台写入线(阳极值);
我是c#新手,正在努力学习一些基础知识。我试图实现一个链表,但当我添加一个节点时,它似乎是通过引用传递的
我第一次打印时得到的正是我所期望的。更改其中一个节点并再次打印列表后,链接列表中的节点值已更改。我如何避免这种情况
public class Node<T>
{
public T value;
private Node<T> next;
public Node(T val)
{
value = val;
next = null;
}
public void SetNext(Node<T> node)
{
var currNode = this;
while (currNode.next != null)
{
currNode = currNode.next;
}
currNode.next = node;
}
public void PrintAllNodes()
{
var currentNode = this;
while (currentNode != null)
{
Console.WriteLine(currentNode.value);
currentNode = currentNode.next;
}
}
}
public class LinkedList
{
public static void Main()
{
var head = new Node<string>("head Node");
head.SetNext(new Node<string>("second node"));
var toChange = new Node<string>("third node");
head.SetNext(toChange);
head.SetNext(new Node<string>("last node"));
head.PrintAllNodes();
Console.WriteLine("----");
toChange.value = "changed!";
//prints "changed!" now
head.PrintAllNodes();
}
}
公共类节点
{
公共价值观;
私有节点下一步;
公共节点(T val)
{
值=val;
next=null;
}
公共void SetNext(节点)
{
var currNode=这个;
while(currNode.next!=null)
{
currNode=currNode.next;
}
currNode.next=节点;
}
public void PrintAllNodes()
{
var currentNode=此;
while(currentNode!=null)
{
Console.WriteLine(currentNode.value);
currentNode=currentNode.next;
}
}
}
公共类链接列表
{
公共静态void Main()
{
var head=新节点(“head节点”);
SetNext(新节点(“第二节点”);
var toChange=新节点(“第三个节点”);
head.SetNext(toChange);
SetNext(新节点(“最后一个节点”);
printalNodes();
控制台写入线(“---”);
toChange.value=“已更改!”;
//现在打印“已更改!”
printalNodes();
}
}
A节点本身就是一个引用。比如说,你没有通过引用传递任何东西。这是一个重要的区别
至于解决方案,一般来说,链接列表中的节点
应该是不可变的。允许在其构造函数中指定节点的内容,然后决不允许对其进行变异,只允许从中读取。如果要使节点的值不可变,因此无法更改它,可以将值
设置为属性
,并给它一个私有设置器
例如
公共类节点
{
公共T值{get;私有集;}
...........
}
或者,如果你出于任何原因想要它,给它一个空的Setter
public class Node<T>
{
private T _value;
public T Value
{
get { return _value; }
set { }
}
}
公共类节点
{
私人T_值;
公共价值
{
获取{返回_值;}
集合{}
}
}
尽管我强烈建议将setter设置为私有,如第一个示例中所示为什么您不希望节点打印输出发生更改?仅代码的答案没有包含解释的答案有用。您绝对不应该让setter不做任何事情。如果不应该设置该值,只需不公开setter.Updated OP和更好的示例即可。@user3490130即使在那个示例中,我也支持我的答案。您的节点几乎可以肯定应该是不可变的,您看到这种行为的原因是因为节点变量本身就是一个引用。
public class Node<T>
{
private T _value;
public T Value
{
get { return _value; }
set { }
}
}