C#引用类型行为

时间:2010-10-01 20:54:20

标签: c# asp.net

我对参考类型有些困惑以下是测试示例 请告诉我它将如何运作

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

** * 修改 * < / EM> ** * ** 应该是什么的输出,以及TestClass()的Object将在执行期间创建的次数。

3 个答案:

答案 0 :(得分:5)

输出应为:

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

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

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

变量testClass的值也通过值传递,但在这种情况下,因为它是引用类型,所以引用的值被传递,因此testClass中的变量Another最初引用与Method中的变量相同的对象。当您在testClass.i中修改Another的值时,它会更改您在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   |
 +-----------+                           +-----------+      +-----------+

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

答案 1 :(得分:4)

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

另一个1:100

另一个2:400

方法1:500

方法2:200

Another方法中的i变量不能在Method方法中更改变量i的值,因为i是值类型;因此,方法(200)中i的值不会因您对Another的调用而改变。   然而,TestClass是一个引用类型,因此Another可以改变其中的字段,因此在行中:

testClass.i = 500;

更改Method所见的值,因此方法1的输出:500。当您在行中分配一个新的TestClass实例时:

testClass = new TestClass();

你已经改变了引用在Another中的内容,但是方法中的原始实例不再可用于方法另一个,因此另一个对其testClass变量做的任何操作都不会对Method引用的实例产生影响< / p>

答案 2 :(得分:0)

基本上,

    testClass.i = 500;

更改对象内的值。您正在传递此对象,因此所有具有对象引用的内容都会看到此更改。但

    i = 400;
    testClass = new TestClass();

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