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();
    }

    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 没有。我的问题是:cin会发生什么TestPassByValByRef

4

4 回答 4

2

当您调用时TestPassByValByRef,您的对象有两个引用 - 引用 inMain和参数引用 to TestPassByValByRefstruct这是因为在 C# 'by value' 中传递引用类型(不是 a 的任何内容)实际上是按值传递引用,而不是对象本身。因此,引用被复制,现在有两个对原始对象的引用。

在调用 之后NowPassByRefTestPassByValByRef引用的副本已被对 的新实例的引用覆盖myclass,但由于Main对象中的引用仍然不符合垃圾回收条件。

所以,“发生了什么”的简短回答是“什么都没有”。

于 2012-06-20T14:45:37.903 回答
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包含两个引用,这两个引用都可以引用 type 的对象myclassc在 之前初始化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;
}

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


你期望会发生什么?

于 2012-06-20T14:49:36.150 回答
0

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

因此,当您在第一种情况下makenew时,您会重新初始化 的副本reference因此它会失去与原始对象的关系。

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

于 2012-06-20T14:43:51.663 回答
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# 通过值/引用传递? 必须是您对问题的解释信息,并查看 John Skeet 关于C# 中的参数传递的文章。

于 2012-06-20T14:48:00.520 回答