2012-10-29 62 views
7

使用它們在下面的代碼中,我嘗試從類TestClass更改某些變量的值,而不必返回它們的主程序中的值。變量在TestClass構造函數中通過引用傳遞。C# - 通過引用傳遞參數給構造函數,然後從方法

class Program 
{ 
    static void Main(string[] args) 
    { 
     int a, b, c, d; 
     a = 5; b = 10; c = 20; d = 25; 
     Console.WriteLine("Main before TestClass: a=" + a + " b=" + b + " c=" + c + " d=" + d); 
     TestClass testObj = new TestClass(ref a,ref b,ref c,ref d); 
     testObj.Work(); 
     Console.WriteLine("Main after TestClass: a=" + a + " b=" + b + " c=" + c + " d=" + d); 
     Console.ReadLine(); 
    } 
} 

public class TestClass 
{ 
    int _a, _b, _c, _d; 
    public TestClass(ref int a, ref int b, ref int c, ref int d) 
    { 
     _a = a; _b = b; _c = c; _d = d; 
    } 

    public void Work() 
    { 
     Console.WriteLine("Work before changing: a=" + _a + " b=" + _b + " c=" + _c + " d=" + _d); 
     _a = 0; _b = 1; _c = 2; _d = 3; 
     Console.WriteLine("Work after changing: a=" + _a + " b=" + _b + " c=" + _c + " d=" + _d); 
    } 
} 

但是這個代碼返回:

Main before TestClass: a=5 b=10 c=20 d=25 
Work before changing: a=5 b=10 c=20 d=25 
Work after changing: a=0 b=1 c=2 d=3 
Main after TestClass: a=5 b=10 c=20 d=25 

有什麼辦法有方法改變主程序中的變量的值? 謝謝!

+2

您需要在'_a'等中存儲*引用*,但您剛剛將它們聲明爲'int's。事實證明,CLR不支持這個概念 - 你*可以*具有引用的局部變量,但不包含字段。 [但是C#甚至不允許你聲明這樣的局部變量](http://blogs.msdn.com/b/ericlippert/archive/2011/06/23/ref-returns-and-ref-locals.aspx)。 –

回答

3

你會過得更好,爲了創建過的Int32自己包裝的變化中反映出來,因爲一旦值分配給類的領域,他們不再是引用,但爲Int32相當不同的情況下, 。請看下面的代碼:

​​

所以,現在你有一個整數 - 過的Int32的包裝類。用法將您帶來的結果:

Integer a = new Integer(0), b = new Integer(0), c = new Integer(0), d = new Integer(0); 
Console.WriteLine("a: {0}, b: {1}, c: {2}, d: {3}", a, b, c, d); 
new TestClass(a, b, c, d).Work(); 
Console.WriteLine("a: {0}, b: {1}, c: {2}, d: {3}", a, b, c, d); 

輸出是:

a: 0, b: 0, c: 0, d: 0 
a: 111, b: 222, c: 333, d: 444 

您也可能會發現,在C#中,例如閱讀更多關於類和結構http://msdn.microsoft.com/en-us/library/ms173109.aspx。 (的Int32是一個結構,而在你的情況,你可能需要一個類)

+0

謝謝,它工作! – panostra

3

不可能。您不能將對int的引用存儲爲成員,只是int a是副本 - 如上所見,對副本的更改不會更改原始內容。

你可以將int包裝在類中。您可以存儲對該類的引用,然後對其進行操作。

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

static void Main(string[] args) 
{ 
    IntWrapper a = new IntWrapper(5); 
    TestClass testObj = new TestClass(a); 
    testObj.Work(); 
} 

public class TestClass 
{ 
    IntWrapper _a; 
    public TestClass(IntWrapper a) 
    { 
     _a = a; 
    } 

    public void Work() 
    { 
     Console.WriteLine("Work before changing: a=" + _a.Value); 
     _a.Value = 0; 
     Console.WriteLine("Work after changing: a=" + _a.Value); 
    } 
} 
2

你試圖做的事情不能完成,因爲它不是以這種方式使用的。您必須直接將參數直接輸入Work方法,例如

testObj.Work(ref a, ref b, ref c, ref d); 
2

這種現象的原因是:

int _a, _b, _c, _d; 
public TestClass(ref int a, ref int b, ref int c, ref int d) 
{ 
    _a = a; _b = b; _c = c; _d = d; 
} 

int是結構(值類型)。這意味着即使您使用ref關鍵字,您也不會按照您的預期將引用(或指針)傳遞到字段。你正在做的是分配給字段的整數值作爲輸入,僅此而已。
爲了達到你期待什麼,你必須使用一個引用類型(包你整成一個類)或引用您的整數(通過ref關鍵字)的方法,你實際上改變它們的值:

public void Work(ref int a, ref int b, ref int c, ref int d) 
{ 
    Console.WriteLine("Work before changing: a=" + a + " b=" + b + " c=" + c + " d=" + _d); 
    a = 0; b = 1; c = 2; d = 3; 
    Console.WriteLine("Work after changing: a=" + a + " b=" + b + " c=" + c + " d=" + _d); 
} 

通過引用傳遞的效果是,在被稱爲方法任何改變參數 反映在調用方法。

要了解關於ref關鍵字的更多信息,請看看:ref (C# Reference)

相關問題