繁体   English   中英

C#引用类型行为

[英]C# reference type behaviour

我对引用类型有些困惑,下面是测试示例,请告诉我它将如何工作

class TestClass
{
    public int i = 100;
}

class MyTestClass
{
    public void Method()
    {
        int i = 200;
        var testClass = new TestClass();
        testClass.i = 300;
        Another(testClass, i);
        Console.WriteLine("Method 1:" + testClass.i);
        Console.WriteLine("Method 2:" + i);
    }
    public void Another(TestClass testClass, int i)
    {
        i = 400;
        testClass.i = 500;
        testClass = new TestClass();
        //If we have set here again testClass.i = 600; what should be out putin this case
        Console.WriteLine("Another 1:" + testClass.i);
        Console.WriteLine("Another 2:" + i);
    }
    public static void Main()
    {
        MyTestClass test = new MyTestClass();
        test.Method();
        Console.ReadLine();
    }
}

** * 编辑 * ** * **这应该是什么输出,以及在执行过程中将创建TestClass()的对象多少次。

输出应为:

Another 1:100
Another 2:400
Method 1:500
Method 2:200

除非使用ref关键字,否则C#将按值传递。 对于值类型,将复制值。 对于引用类型,将复制引用的

变量itestClass.i完全无关。 我先来看一个简单的例子, i是一个int-值类型。 当您使用i作为参数调用方法Another ,它会通过值传递,因此在方法Another修改i的值不会更改Method变量i的值-它始终等于200。

变量testClass的值也按值传递,但在这种情况下,因为它是引用类型,所以传递了引用的值,因此Another的变量testClass最初与Method的变量引用同一对象。 当您在“ Another修改testClass.i的值时,它将更改您在“ Method创建的对象,以便将其成员设置为300。

然后,此行创建一个新的不相关的对象:

testClass = new TestClass();

有时,更容易查看图中发生的情况,其中上排显示变量,下排显示它们引用的对象:

Before assignment:                      After assignment:

+-------------+    +-------------+      +-------------+    +-------------+
| Method      |    | Another     |      | Method      |    | Another     |
| testClass   |    | testClass   |      | testClass   |    | testClass   |
+-------------+    +-------------+      +-------------+    +-------------+
       |                  |                    |                  |
       |                  |                    |                  |
       v                  |                    v                  v
 +-----------+            |              +-----------+      +-----------+
 | TestClass |<-----------+              | TestClass |      | TestClass |
 | i = 300   |                           | i = 300   |      | i = 100   |
 +-----------+                           +-----------+      +-----------+

因此,在“ Another打印时, testClass.i的值是在构造函数中设置的默认值,即100。赋值不会修改原始对象。 您只是在重新分配变量以指向其他对象。

在C#中,任何结构都是值类型,任何类都是引用类型。 当您将值类型作为参数传递给另一个方法时,该方法将无法更改原始值(除非使用ref关键字传递值类型)。 当您将引用类型作为参数传递给另一个方法方法时,该方法对该对象所做的任何更改都会在从该方法返回时反映在该对象中。 输出为:

另一个1:100

另一个2:400

方法1:500

方法2:200

Another方法中的i变量无法更改Method方法中的变量i的值,因为i是值类型; 因此,通过调用“另一个”,方法(200)中的i值将保持不变。 但是,TestClass是引用类型,因此Another可以更改其中的字段,因此在行中:

testClass.i = 500;

更改方法所看到的值,因此是方法1:500的输出。 当您在该行中分配TestClass的新实例时:

testClass = new TestClass();

您已更改了“另一个”中引用的内容,但是“方法”中的原始实例不再可用于“另一个”方法,因此“另一个”对其testClass变量所做的任何操作均不会影响该方法所引用的实例

基本上,

    testClass.i = 500;

更改对象内部的值。 您正在传递该对象,因此所有对该对象都有引用的对象都可以看到此更改。

    i = 400;
    testClass = new TestClass();

这些分配仅更改本地参数的值。 同一方法之外的任何代码都看不到此更改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM