简体   繁体   English

为什么不能在函数中实例化对象

[英]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.

相关问题 这是对适配器模式的正确使用吗? 我无法实例化该对象? - Is this a correct Use Of Adapter Pattern? I can't instantiate this object? 为什么我不能在XAML中定义ResourceDictionary并单独实例化它? - Why can't I define a ResourceDictionary in XAML and instantiate it by itself? 我可以模拟无法实例化的对象吗? - Can I mock object which is impossible to instantiate? 我可以从字符串开始并实例化该字符串的对象吗? - Can I start with a string and instantiate an object of that string? 我收到一个错误,因为我无法实例化另一个对象 - I get an error because I can't instantiate an object inside another 无法重新实例化/重生我在Unity3D中销毁的对象 - Can't re-instantiate/respawn object I've destroyed in Unity3D 为什么在Portable Library类中我无法实例化ValidationContext以及如何修复它? - Why in Portable Library classes I can't instantiate a ValidationContext and how to fix it? 为什么不能在WP7单元测试项目中实例化我的页面之一? - Why can't I instantiate one of my Pages in a WP7 unit test project? 为什么不能实例化Win32_PowerMeter WMI类? - Why can't I instantiate the Win32_PowerMeter WMI class? 为什么不实例化对象会自动实例化其属性? - Why doesn't instantiating an object automatically instantiate its properties?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM