如果您有一个带有对象输入参数的类和构造函数 - 那么该对象是按引用传递还是按值传递?
对于类方法,假设对象输入参数默认情况下是按值传递的,除非使用ref关键字,这是正确的吗?
那么out关键字呢?这是否仍意味着它是按引用传递的?
如果您有一个带有对象输入参数的类和构造函数 - 那么该对象是按引用传递还是按值传递?
对于类方法,假设对象输入参数默认情况下是按值传递的,除非使用ref关键字,这是正确的吗?
那么out关键字呢?这是否仍意味着它是按引用传递的?
out
或 ref
,否则在 C# 中所有参数都是按值传递的。这是一个非常令人困惑的地方。我来更明确地说明一下:所有参数都会复制其值,除了那些被标记为 out
或 ref
的参数。对于值类型,这意味着传递的值会被复制一份。对于引用类型,这意味着传递的引用会被复制一份。对于最后一点,引用类型的值就是该引用。ref
关键字,我们是否可以默认认为对象输入参数是按值传递的呢?out
或 ref
,否则所有参数都是按值传递的。对于标记为 ref
的参数,将传递该参数的引用到方法中,现在您可以把该参数看作是一个别名。因此,当你说void M(ref int m) { m = 10; }
int n = 123;
M(ref n);
您可以将 M
中的 m
视为 n
的别名。也就是说,m
和 n
只是同一存储位置的两个不同名称。
这与其他情况非常不同。
string s = "Hello, world!";
string t = s;
s
和t
不是指向同一存储位置的别名。它们是两个不同的变量,恰好引用同一个对象。
那么`out`关键字呢?这是否意味着它仍然是按引用传递的?
ref
和 out
之间唯一的区别是 ref
要求在传递之前初始化变量。对象的引用将按值传递。
.NET有引用类型和值类型——类都是引用类型,结构体是值类型。您可以按值或按引用传递任何一种类型。
默认情况下,所有内容都按值传递,不同之处在于对于引用类型,将传递引用。
ref
和out
关键字将导致参数按引用传递——对于值类型,这意味着您现在可以进行更改,并将反映在传递的对象中。对于引用类型,这意味着您现在可以更改引用所指向的对象。
一个 对象
总是通过引用传递给实际对象。因此,不会对对象执行任何副本(又称“按值”)。
正如 Oded 所指出的那样,对象的引用被复制。
ref
或 out
参数)。 - LukeH@Supercat:这相当有趣。也许混淆在于理解为什么要通过引用类型传递引用!
将类比仅扩展到 ref 类型(我认为值类型更容易理解)
一个人可以在多张纸片上写出相同的 VIN(车辆识别号码),因此你手上所有的纸条都指向同一辆车。如果你在一张纸条上写下“油漆蓝色”,在另一张纸条上写下“油漆红色”会发生什么?这说明纸条只能包含VIN(对象地址),而所有其他信息都存储在汽车本身中。
如果你想在工作室给车涂漆,你不必发送一张纸条,你只需告诉他们VIN就行了,这只是需要知道的值 - 按值传递。你仍然保留你的纸条,他们不能更改上面的内容...因此更安全。因此,他们在自己的纸条上写下VIN-引用的副本。
另一方面,您可以向同事索取上次洗过的汽车的单据,前往前场选择一辆不是上次洗过的汽车,并在其上写下已洗车辆的新VIN码,然后将单据归还 - 按引用。使用实际单据并引用实际单据的地址(架子),以便他从那里获取单据。最好不要丢失或弄湿它...不太安全。
在所有这些混乱中,没有人谈论复制、拿走或移动实际汽车,因为这不涉及值类型。
.Net中参数的默认传递机制是按值传递。这对于引用类型和值类型都是正确的。在引用类型的情况下,实际上传递的是引用本身,而不是对象。
当使用ref
或out
关键字时,值确实是按引用传递的(对于值类型和引用类型都是如此)。在CLR级别上,实际上ref
和out
之间没有任何区别。 out
关键字是C#的一个概念,通过标记ref
参数来表示(我相信这是通过modopt完成的)。
它是按值传递的,如果您打算按引用传递它,您将使用ref
参数修饰符。不确定这是否允许在构造函数中使用...