2012-11-30 29 views
6

引用類型,我想:如何使從int

int i = 5; 
object o1 = i; // boxing the i into object (so it should be a reference type) 
object o2 = o1; // set object reference o2 to o1 (so o1 and o2 point to same place at the heap) 

o2 = 8; // put 8 to at the place at the heap where o2 points 

運行此代碼後,在01值仍是5,但我預計8

我缺少的東西?

+7

拳擊不改變它的類型。它應該保持一個值類型。 –

+2

我不認爲使用對象實際上使int成爲引用類型;它存儲一個未確定的類型,但.NET保持對該對象的理解(它知道它是一個int,它不是引用類型)。 –

+1

裝箱值的類型是不可變的。賦值'o2 = 8;'創建一個新的盒裝int,並使其成爲'o2'的引用。另一個變量「o1」仍然指向第一個裝箱的int。字符串也是如此:'string s1 =「5」;字符串s2 = s1; s2 =「8」;'實際上,可變參考類型也是如此:'列表 x =新列表 {5};列表 y = x; y =新列表 {8};' – phoog

回答

14

這不是C#中變量的工作方式。它與拳擊價值類型無關。

考慮一下:

object o1 = new object(); 
object o2 = o1; 

o2 = new object(); 

爲什麼你會想到o1o2包含對同一對象的引用?當你設置o2 = o1時,它們是相同的,但是一旦你設置了o2 = new object()o2的值(變量指向的內存位置)就會改變。

也許你正在試圖做什麼可以做這樣的:

class Obj { 
    public int Val; 
} 

void Main() { 
    Obj o1 = new Obj(); 
    o1.Val = 5; 
    Obj o2 = o1; 
    o2.Val = 8; 
} 

截至Main年底,o1Val屬性將包含8

0

正如Joel指出,儘管盒裝它仍然是一個值類型,因此它沒有被引用它被克隆。這就是爲什麼你會看到這個結果 - o1和o2指向不同的內存位置。

4

做你想做的事,值必須是引用類型的屬性:

public class IntWrapper 
{ 
    public int Value { get; set; } 
    public IntWrapper(int value) { Value = value; } 
} 

IntWrapper o1 = new IntWrapper(5); 
IntWrapper o2 = o1; 

o2.Value = 8; 
1

@Ken給你完美的答案。這一個是如何獲得與struct(值類型)相同的行爲。

注意:可變值類型有非常不直觀的行爲,不要在家中嘗試這:)。

要獲得與值類型相似的行爲,您需要實現一些接口並通過接口設置屬性,因爲將自己的類型拆箱struct將始終創建副本,並且您將無法修改原始值。

void TortureMutableBoxedValueType() 
{ 
    object o1 = new IntWrapper(5); 
    object o2 = o1; 
    Console.WriteLine(((IValue)o1).Value); // outputs original 5 
    ((IValue)o2).Value = 8; 
    Console.WriteLine(((IValue)o1).Value); // outputs new 8 
} 

interface IValue 
{ 
    int Value {get;set;} 
} 

// Don't use mutable value types - this is just sample. 
public struct IntWrapper : IValue 
{ 
    int v; 
    public int Value { get { return v;} set {v = value;}} 
    public IntWrapper(int value) { v = value; } 
} 
+0

爲什麼這是低調的?這實際上非常有趣,並且證明我沒有意識到的行爲(假設它按照廣告的方式工作......我沒有自己嘗試過)。 +1 – ken