C# 对象按引用传递或按值传递
本文关键字:按值传递 按引用传递 对象 | 更新日期: 2023-09-27 18:33:23
以下代码的输出让我感到惊讶。我认为"a"应该包含对新创建对象的引用。有人可以解释为什么结果不是 2 吗?
class Program
{
static void Main(string[] args)
{
aclass a = new aclass();
Process(a);
Console.WriteLine(a.number);
Console.ReadLine();
}
static void Process(aclass a)
{
aclass temp = new aclass();
temp.number++;
//Console.WriteLine(temp.number);
a = temp;
a.number++;
//Console.WriteLine(a.number);
}
}
class aclass
{
public int number = 0;
}
编辑:这是一个面试问题。我只是意识到我误解了这个概念很长时间。参数 a 与原始 a 不同,尽管它们引用相同的地址。
您不会更改实际的原始引用,您只是更改参数中保存的引用,这显然是不一样的,更改不会保留回调用方。您可以使用 out
或 ref
来更改此行为。
在这种情况下,您特别希望使用ref
,因为您还要传入引用。
尝试:
class Program
{
static void Main(string[] args)
{
aclass a = new aclass();
Process(ref a);
Console.WriteLine(a.number);
Console.ReadLine();
}
static void Process(ref aclass a)
{
aclass temp = new aclass();
temp.number++;
//Console.WriteLine(temp.number);
a = temp;
a.number++;
//Console.WriteLine(a.number);
}
}
请记住,您正在使用 a = temp
分配一个全新的引用。如果您只想更新最初传入的现有类,则可以执行以下操作:
a.number = temp.number;
a.number++;
这将否定对ref
的需求。
您可以在 MSDN 上阅读更多信息:
传递引用类型参数
参考关键字
出关键字
这一行aclass a = new aclass();
内存中创建一个变量(我们可以存储数据的空间)。考虑它在内存中的地址是*(0x12DF)
,存储在该位置的value
是对象a
这一行Process(a)
传递对象a
而不是地址的VALUE
来Process
,所以Process()
中发生的任何事情都与位置*(0x12DF)
contents
无关,所以位置*(0x12DF)
的内容将保持与调用Process()
之前相同。
内容 *(0x12DF)
= A
我希望它有帮助,而不是造成更多的混乱!!
基本上是两者之间的区别
- 按值传递引用类型//进程(a);
- 通过引用传递引用类型//进程(ref a);
在示例中,Process(a) - 'a' 是一个引用类型,被传递给没有 ref 参数的方法。在这种情况下,指向 的引用副本将传递给该方法。
通过在 Process 方法中使用 new 运算符分配内存的新部分,使变量 'a' 引用 aclass 的新对象。因此,之后的任何更改都不会影响原始对象"a"。
请参阅 MSDN : http://msdn.microsoft.com/en-us/library/s6938f28.aspx