以下代码的输出让我感到惊讶。我认为“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不同,尽管它们引用相同的地址。
答案 0 :(得分:10)
您没有更改实际的原始引用,您只是更改参数中保存的引用,这些引用略微不相同,更改不会持久保存回调用者。您可以使用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上阅读更多内容:
答案 1 :(得分:0)
这一行aclass a = new aclass();
在内存中创建一个变量(我们可以存储数据的空间)。请考虑其在内存中的地址为*(0x12DF)
,并且存储在该位置的value
为对象a
此行Process(a)
将VALUE
对象a
非地址传递给Process
,因此Process()
中发生任何事情}与位置contents
的{{1}}无关,因此位置*(0x12DF)
的内容将与调用*(0x12DF)
之前的内容保持一致。
Process()
= a
我希望它有用而不是造成更多混乱!!
答案 2 :(得分:0)
基本上是
之间的区别在示例中,过程(a) - ' a'这是一个引用类型,传递给没有ref参数的方法。在这种情况下,引用的副本(指向a)将传递给方法。
通过在Process方法中使用new运算符来分配新的内存部分,可以使变量成为一个' a'引用一个新的aclass对象。因此,之后的任何更改都不会影响原始对象' a'。
请参阅MSDN:http://msdn.microsoft.com/en-us/library/s6938f28.aspx