[英]Why can't I instantiate an object in a function
So basically I have a class NodeTree: 所以基本上我有一个NodeTree类:
public class NodeTree
{
public NodeTree(int value, NodeTree left, NodeTree right)
{
Value = value;
Right = right;
Left = left;
}
public int Value { get; set; }
public NodeTree Right { get; set; }
public NodeTree Left { get; set; }
}
And in my main I want to do something like 我主要想做的是
NodeTree root = null;
Algo.InsertValueIt(root, 8);
Where InsertValueIt() is a method from my static class Algo which does : 其中InsertValueIt()是我的静态类Algo中的一种方法,该方法可以:
public static void InsertValueIt(NodeTree root, int val)
{
var newNode = new NodeTree(val, null, null);
if (root == null)
{
root = newNode;
}
}
Everything is working as expected in my method, but back to my main, my object root is still null. 一切都按我的方法预期进行,但回到主目录,我的对象根仍然为null。 The reason I am confused is that I give to my method a reference, so it should modify the value of the adress to the new space I am allocating.
我感到困惑的原因是我给了我的方法一个参考,因此它应该将地址的值修改为我要分配的新空间。
I think I can solve my problem by just returning a NodeTree, but is there a way of doing it with a void return type? 我认为我可以通过返回NodeTree来解决问题,但是有没有一种方法可以使用void返回类型呢?
You need to define your argument to be passed by reference in order to modify the original value (note the ref
keyword): 您需要定义要通过引用传递的参数,以便修改原始值(请注意
ref
关键字):
public static void InsertValueIt(ref NodeTree root, int val) {
...
Also when calling the method, you need to mark the parameter with ref
: 同样,在调用方法时,您需要使用
ref
标记参数:
Algo.InsertValueIt(ref root, 8);
... otherwise you only modify the local copy in that function. ...否则,您只能在该功能中修改本地副本。
What happens when you pass a reference type to a method? 将引用类型传递给方法时会发生什么?
The variable declared to be of a reference type holds the memory address where the instance of the type has been allocated (the root in the calling code). 声明为引用类型的变量保存该类型的实例已分配到的内存地址(调用代码中的根 )。 The value of this address is copied to a new variable created on the stack for the called method (the root in the
InsertValueIt
). 此地址的值被复制到在堆栈上为调用的方法创建的新变量(
InsertValueIt
的根 )。 Using that address through the new variable you will be able to change every public property of the instance or call any methods (provided that the address passed is not null). 通过新变量使用该地址,您将能够更改实例的每个公共属性或调用任何方法(前提是所传递的地址不为null)。
What happens now if you call new on this local variable? 如果在此局部变量上调用new会发生什么?
A new block of memory is allocated on the heap for the type, the constructor is called to initialize everything, and the memory address of this block is stored in the LOCAL variable inside the InsertValueIt
. 在堆上为该类型分配一个新的内存块,调用构造函数初始化所有内容,并将该块的内存地址存储在
InsertValueIt
内部的LOCAL变量中。
Your original one, (the root in the calling code), is unaffected by this change. 原始更改(调用代码的根)不受此更改的影响。 (still holds null).
(仍为null)。 Using the ref keyword makes the this 'problem' disappear, but I suggest to use a method that creates the Node and return it to the calling method instead.
使用ref关键字会使此“问题”消失,但是我建议使用一种创建Node并将其返回给调用方法的方法。
If you want to understand in more depth this subject I recommend these two articles: 如果您想更深入地理解该主题,我建议您阅读以下两篇文章:
C#Concepts: Value Types vs Reference Types from Joseph Albahari C#概念: Joseph Albahari的 值类型与引用类型
Parameter Passing in C# from Jon Skeet 从Jon Skeet的 C#中传递参数
您在InsertValueIt中分配的根值未在任何执行路径中使用,因此应在参数声明中添加ref关键字。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.