2009-10-11 51 views
1

是C#Object/object值類型或引用類型?C#對象/對象

我檢查了他們可以保留引用,但是這個引用不能用來改變對象。

using System; 

class MyClass 
{ 
    public static void Swap(Object obj1, Object obj2) 
    { 
     Console.WriteLine("After Swapping"); 
     obj1 = 100; 
     obj2 = 200; 
    } 
} 

class MainClass 
{ 
    static void Main(string[] args) 
    { 
     Object obj1 = new Object(); 
     obj1 = 10; 

     Object obj2 = new Object(); 
     obj2 = 20; 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     MyClass.Swap(obj1, obj2); 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     Console.ReadLine(); 
    } 
} 
+0

請張貼一些代碼,證明您不能更改對象引用。 – Kobi 2009-10-11 08:27:31

回答

5

更改您在Swap使僅限於那裏 - 你只使用指針(和拳擊)打,在函數外引用保持不變(你有4個參考)。如果您更改了方法的簽名,則會看到差異:

嘗試Swap(ref Object obj1, ref Object obj2)

也是一樣

Object obj1 = new Object(); 
obj1 = 10; 

這並不比Object obj1 = 10;更好,通過

要查看對象實際上是一個引用類型,使用一類具有的屬性,例如方式:

class Foo { 
    public int Value {get; set;} 
} 

更改Swap中對象的Value,您將看到對主程序的影響。

4

這是一個引用類型 - 如果你看一下documentation,你會看到它的聲明爲類。所有的類都是引用類型。

是的,System.ValueTypeSystem.Enum也是如此 - 它們都是引用類型,儘管名稱...值類型從它們派生。

編輯:您的更新顯示,你真正困惑的是參數傳遞。請參閱我的文章parameter passing in C#reference/value types

+0

plz查看更新。 – anonymous 2009-10-11 08:32:52

+0

我從來不知道System.ValueType本身就是一個引用類型...我總是認爲它是一個值類型。它看起來像是一個引用類型,因此可以重寫Equals()和GetHashCode()來比較內容。 – overstood 2009-10-11 10:33:29

+1

更多的是,作爲一個值類型本身,沒有任何東西可以從它派生出來...... – 2009-10-11 11:22:01

0

你應該寫這樣的代碼:

using System; 

class MyClass 
{ 
    public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref' 
    { 
     Console.WriteLine("After Swapping"); 
     obj1 = 100; 
     obj2 = 200; 
    } 
} 

class MainClass 
{ 
    static void Main(string[] args) 
    { 
     Object obj1 = new Object(); 
     obj1 = 10; 

     Object obj2 = new Object(); 
     obj2 = 20; 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     MyClass.Swap(ref obj1, ref obj2); // Use keyword 'ref' 

     Console.WriteLine(obj1.ToString()); 
     Console.WriteLine(obj2.ToString()); 

     Console.ReadLine(); 
    } 
} 

可以在MSDN

報價從MSDN瞭解關鍵字 '裁判' 的更多信息:

傳遞參數(C#編程 指南)

在C#中,參數可以傳遞 按價值或參考。通過引用傳遞 參數可使 函數成員,方法,屬性, 索引器,運算符和構造函數 更改參數 的值,並使該更改保持不變。要通過引用傳遞參數 ,請使用參考號 或out關鍵字。爲了簡單起見,本主題中的 示例中僅使用 ref關鍵字。有關ref和out之間的差異 的更多信息,請參閱參考資料(C# 參考),out(C#參考)和 使用ref和out傳遞數組(C# 編程指南)。例如:

// Passing by value 
static void Square(int x) 
{ 
    // code... 
} 
// Passing by reference 
static void Square(ref int x) 
{ 
    // code... 
} 

(c)中MSDN - Passing Parameters (C# Programming Guide)

0

這是因爲OBJ1和OBJ2的運行時類型是System.Int32(帶obj1.GetType().ToString()檢查),即,值類型。您的交換功能沒有參考副本。相反,它只是執行裝箱和取消裝箱操作,這些操作對實際變量沒有影響。

+0

這不會爲引用類型工作,不只是'int' - 做'obj1 = new Foo();'在本地更改引用在功能上。 – Kobi 2009-10-11 08:48:21

2

請注意,

Object obj1 = new Object(); 
obj1 = 10; 

相同:

Object obj1 = 10; 

由於編譯器與「拳擊」干預打開值型int成引用類型。而在你的Swap方法中,你再次裝箱,覆蓋參考參數。

所以了Kobi的和夢遊者的解決方案,使用ref參數,將實際工作:

public static void Swap(ref Object obj1, ref Object obj2) // Use keyword 'ref' 

但很不理想。

更好的解決方案將是一個通用的方法:

static void Swap<T>(ref T x, ref T y) 
{ 
    T z = x; x = y; y = z; 
} 

因此,編譯器可以產生參比和價值類型最合適的代碼。

+0

從什麼時候開始10 = 100? – RCIX 2009-10-11 09:05:24