[英]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#將按值傳遞。 對於值類型,將復制值。 對於引用類型,將復制引用的值 。
變量i
與testClass.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.