4

以下代码的输出让我感到惊讶。我认为“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 不同,尽管它们引用相同的地址。

4

3 回答 3

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 上阅读更多内容:

传递引用类型参数

参考关键字

出关键字

于 2013-10-01T10:36:53.843 回答
0

这一行在aclass a = new aclass();内存中创建了一个变量(我们可以存储数据的空间)。考虑它在内存中的地址是*(0x12DF),并且value存储在该位置的是对象a

此行将of 对象NOT THE ADDRESSProcess(a)传递给函数,因此发生的任何事情都与of location无关,因此 location 的内容将保持与调用之前相同。VALUEa ProcessProcess()contents*(0x12DF)*(0x12DF)Process()

内容*(0x12DF)= 一个

我希望它有所帮助,而不是造成更多的混乱!

于 2013-10-01T11:02:17.233 回答
0

这基本上是之间的区别

  • 按值传递引用类型 // Process(a);
  • 通过引用传递引用类型 // Process(ref a);

在示例中,Process(a) - 'a' 是一个引用类型,它被传递给没有 ref 参数的方法。在这种情况下,将指向 a 的引用的副本传递给该方法。

通过在 Process 方法中使用 new 运算符分配新的内存部分,使变量“a”引用 aclass 的新对象。因此,此后的任何更改都不会影响原始对象“a”。

参考 MSDN:http: //msdn.microsoft.com/en-us/library/s6938f28.aspx

于 2013-10-01T11:15:07.613 回答