我为一个类声明了一个变量,并将其传递给一个方法来实例化它,但原始变量仍未实例化

Posted

技术标签:

【中文标题】我为一个类声明了一个变量,并将其传递给一个方法来实例化它,但原始变量仍未实例化【英文标题】:I declared a variable for a class, and passed it into a method to instantiate it, but the original variable remains uninstantiated 【发布时间】:2015-12-25 20:18:07 【问题描述】:

我知道类总是通过引用传递不同于通过值传递的结构。

如果你看一下下面的代码,你会发现我调用了一个没有ref 关键字的函数(假设不​​需要它,因为Path 是一个类,因此它应该总是由 ref 自动调用不需要ref 关键字)。

public MainWindow()

    InitializeComponent();      
    Func(myPath);

    if (myPath == null)
       MessageBox.Show("AAAARGH");


Path myPath;

private void Func(Path p)

    if (p == null)
        p = new Path();

所以在函数调用之后,我希望myPath 不再是null,因为它已在Func() 中初始化,但事实并非如此。

我正在研究全球价值。这会改变什么吗?

【问题讨论】:

通过引用传递,如果没有 ref 关键字,您仍然无法更改该引用指向的位置。您可以修改该对象的属性,但不能创建新对象并将其保留回调用者。 这真是糟糕的设计。为什么不直接使用myPath?此外,无论您在做什么,它都不属于后面的代码。创建合适的 ViewModel。 我正在制作多路径画布。相同的功能既可以在新路径上操作,也可以在用户通过鼠标选择的路径上操作。这就是为什么我有一个代表 mouseSelectedPath 的 myPath。那就是说你是对的,我将重新阐述我的代码,尽量不使用全局路径。还有一件事:为什么不使用代码隐藏?这是一个相当复杂的程序,所以我无法将所有内容都放在 xaml 文件中。 错了。如果参数没有refout,则一切(无论类型如何)都是按值传递。如果参数具有refout,则所有内容(无论类型如何)都是通过引用传递的。 【参考方案1】:

通过引用传递值与使用ref 关键字非常不同。将其翻译成 C 或 C++ 术语:

传递一个对象就像传递一个指针 传递一个对象 ref 就像将指针传递给指针。

如果要更改函数内部变量的值,则需要使用refout

【讨论】:

通过引用传递完全是使用ref关键字。【参考方案2】:

你必须用'out'标记参数。

有关“out”的更多信息,请查看:

https://msdn.microsoft.com/en-us/library/t3c3bfhx.aspx

【讨论】:

在所描述的场景中,'out' 的使用优于 'ref',因为它可以更清晰地传达方法调用的意图。再一次,最准确的答案没有得到复选标记。【参考方案3】:

当您最初调用Func()myPathp 时,引用Path 的同一个实例。但是,myPathp 仍然是两个独立的引用,它们恰好指向同一个实例。

也就是说,直到下面的代码运行:

p = new Path();

之后,p 引用了一个与原始实例不同的 Path 的新实例。更改p 引用的实例中的属性将不会反映在myPath 引用的实例中。

换句话说:

private void Func(Path p)  // p is a separate reference, referencing same Path as myPath

    if (p == null)         // p still references same Path as myPath
        p = new Path();    // now p references a new instance of Path, separate from myPath

您可以使用ref(或out)关键字,以便myPath 标识的引用本身是“按引用”传递的,其效果是myPathp 是一个单一的参考。

然后,当您在方法中创建 Path 的新实例时,myPathp 仍然是一个引用,都指向新实例。 (您的原始实例仍在内存中某处,但不再引用它。)

Path myPath = null;

private void Func(ref Path p)  // p is same reference as myPath

    if (p == null)
        p = new Path();        // p and myPath are still same reference,
                               //   now referencing a new instance of Path

或者:

Path myPath;

private void Func(out Path p)  // p is same reference as myPath

    if (p == null)     
        p = new Path();        // p and myPath are still same reference,
                               //   now referencing a new instance of Path

【讨论】:

错了。 “类的实例”不是 C# 中的值,不能“通过”。当你创建一个实例时,你会得到一个reference(一个引用类型的值),你只能通过这些references来操作实例。这些引用可以按值(不带refout)或通过引用(带refout)传递。

以上是关于我为一个类声明了一个变量,并将其传递给一个方法来实例化它,但原始变量仍未实例化的主要内容,如果未能解决你的问题,请参考以下文章

获取 Javascript 变量并将其传递给 PHP 函数 [重复]

在 JavaScript 中创建类并将其传递给 MVC 控制器的正确方法是啥

如何将数据源从一个模块引用到另一个模块并将其作为变量传递给根模块?

python 类中的变量传递给类中的函数

将值从数据库传递到 vue 组件并将其分配给变量

将二维数组传递给另一个类 C++