按值传递对象,然后按引用传递

时间:2012-06-20 14:41:41

标签: c# .net pass-by-reference pass-by-value

我有以下代码:

   static void Main(string[] args)
    {
        myclass c = new myclass();

        c.test1 = 1;

        myclass c2 = TestPassByValByRef(c);

        Console.WriteLine("c.Test1: {0}", c.test1);
        Console.WriteLine("c2.Test1: {0}", c2.test1);
        Console.ReadLine();
    }

    private static myclass TestPassByValByRef(myclass c)
    {
        Console.WriteLine("Before NowPassByRef c.Test1: {0}", c.test1);
        NowPassByRef(ref c);
        Console.WriteLine("After NowPassByRef c.Test1: {0}", c.test1);

        return c;
    }

    private static void NowPassByRef(ref myclass c)
    {
        c = new myclass();
        c.test1 = 10;
        c.test2 = 25;
    }

输出是c2保留更改的值,而c不保留。 我的问题是:c中的TestPassByValByRef会发生什么?

4 个答案:

答案 0 :(得分:2)

当您致电TestPassByValByRef时,您的对象有两个引用 - Main中的引用,以及TestPassByValByRef参数的引用。这是因为在C#'中按值传递引用类型(不是struct的任何内容)实际上是按值传递引用,而不是对象本身。因此,复制了引用,现在有两个对原始对象的引用。

调用NowPassByRef后,TestPassByValByRef的参考副本已被myclass的新实例的引用覆盖,但由于Main中仍有引用1}}该对象不符合垃圾回收的条件。

因此,对“发生的事情”的简短回答是“没有”。

答案 1 :(得分:0)

在第一种情况下,您将{strong>按值 a reference传递给您的对象。

因此,当您在第一种情况下执行 时,您需要new,重新初始化reference副本,因此它将失去与原始物体。

在第二种情况下,您传递reference 本身,因此使用new重新初始化它也会更改它指向的内存位置。

答案 2 :(得分:0)

在您的以下代码中,您c = new myclass();object c创建一个新的内存引用,该引用不指向已通过的内存。因此,您无法将更改反映到您创建的第一个对象。

private static void NowPassByRef(ref myclass c)
    {
        c = new myclass();  // it will create new memory reference
        c.test1 = 10;
        c.test2 = 25;
    }

因此它将显示c不会被更改并输出为:

Before NowPassByRef c.Test1: 1
After NowPassByRef c.Test1: 10
c.Test1: 1
c2.Test1: 10

暂时只评论方法中的c = new myclass();,它会反映object c的更改。它将清除你对引用指针等的怀疑。

private static void NowPassByRef(ref myclass c)
        {
            //c = new myclass();  // it will create new memory reference
            c.test1 = 10;
            c.test2 = 25;
        }

现在输出将是:

Before NowPassByRef c.Test1: 1
After NowPassByRef c.Test1: 10
c.Test1: 10
c2.Test1: 10
  

我认为 -   C# pass by value/ref?   必须是您解释的问题信息并检查John   Skeet关于Parameter passing in C#的文章。

答案 3 :(得分:0)

static void Main(string[] args)
{
    myclass c = new myclass();

    c.test1 = 1;

    myclass c2 = TestPassByValByRef(c);

    Console.WriteLine("c.Test1: {0}", c.test1);
    Console.WriteLine("c2.Test1: {0}", c2.test1);
    Console.ReadLine();
}

main包含两个引用,这两个引用都可以引用myclass类型的对象。在c之前初始化TestPassByValByRefc2由该方法的返回值初始化。

private static myclass TestPassByValByRef(myclass c)
{
    Console.WriteLine("Before NowPassByRef c.Test1: {0}", c.test1);
    NowPassByRef(ref c);
    Console.WriteLine("After NowPassByRef c.Test1: {0}", c.test1);

    return c;
}

TestPassByValByRef包含一个名为c的引用。它最初包含作为参数传递给它的引用的副本(因为该参数是按值传递的)。 然后通过引用NowPassByRef传递此引用并返回。

private static void NowPassByRef(ref myclass c)
{
    c = new myclass();
    c.test1 = 10;
    c.test2 = 25;
}

NowPassByRef与其调用方法共享引用c。它会在返回之前立即将其重新分配给新值。


您期望发生什么?