c#对象按引用传递或按值传递

时间:2013-10-01 10:33:48

标签: c# object-reference

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

3 个答案:

答案 0 :(得分:10)

您没有更改实际的原始引用,您只是更改参数中保存的引用,这些引用略微不相同,更改不会持久保存回调用者。您可以使用outref更改此行为。

在这种情况下,你特别想要使用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上阅读更多内容:

Passing Reference Type Parameters

ref Keyword

out Keyword

答案 1 :(得分:0)

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

此行Process(a)VALUE对象a 非地址传递给Process,因此Process()中发生任何事情}与位置contents的{​​{1}}无关,因此位置*(0x12DF)的内容将与调用*(0x12DF)之前的内容保持一致。

Process() = a

的内容

我希望它有用而不是造成更多混乱!!

答案 2 :(得分:0)

基本上是

之间的区别
  • 按值传递参考类型//处理(a);
  • 按引用传递引用类型//处理(ref a);

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

通过在Process方法中使用new运算符来分配新的内存部分,可以使变量成为一个' a'引用一个新的aclass对象。因此,之后的任何更改都不会影响原始对象' a'。

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