我为一个类声明了一个变量,并将其传递给一个方法来实例化它,但原始变量仍未实例化
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 文件中。
错了。如果参数没有ref
或out
,则一切(无论类型如何)都是按值传递。如果参数具有ref
或out
,则所有内容(无论类型如何)都是通过引用传递的。
【参考方案1】:
通过引用传递值与使用ref
关键字非常不同。将其翻译成 C 或 C++ 术语:
ref
就像将指针传递给指针。
如果要更改函数内部变量的值,则需要使用ref
或out
。
【讨论】:
通过引用传递完全是使用ref
关键字。【参考方案2】:
你必须用'out'标记参数。
有关“out”的更多信息,请查看:
https://msdn.microsoft.com/en-us/library/t3c3bfhx.aspx
【讨论】:
在所描述的场景中,'out' 的使用优于 'ref',因为它可以更清晰地传达方法调用的意图。再一次,最准确的答案没有得到复选标记。【参考方案3】:当您最初调用Func()
、myPath
和p
时,引用Path
的同一个实例。但是,myPath
和 p
仍然是两个独立的引用,它们恰好指向同一个实例。
也就是说,直到下面的代码运行:
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
标识的引用本身是“按引用”传递的,其效果是myPath
和p
是一个单一的参考。
然后,当您在方法中创建 Path
的新实例时,myPath
和 p
仍然是一个引用,都指向新实例。 (您的原始实例仍在内存中某处,但不再引用它。)
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来操作实例。这些引用可以按值(不带ref
或out
)或通过引用(带ref
或out
)传递。以上是关于我为一个类声明了一个变量,并将其传递给一个方法来实例化它,但原始变量仍未实例化的主要内容,如果未能解决你的问题,请参考以下文章
获取 Javascript 变量并将其传递给 PHP 函数 [重复]
在 JavaScript 中创建类并将其传递给 MVC 控制器的正确方法是啥