[英]C# - passing parameters by reference to constructor then using them from method
在下面的代碼中,我試圖讓TestClass類的method(Work)更改主程序中某些變量的值,而不必返回它們。 變量在TestClass構造函數中通過引用傳遞。
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
有什么方法可以讓該方法在主程序中更改變量的值? 謝謝!
不可能。 您不能將對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);
}
}
您最好在Int32上創建自己的包裝程序以反映更改,因為一旦將值分配給該類的字段,它們就不再是引用,而是Int32的不同實例。 考慮以下代碼:
class Integer {
public int Value;
public Integer(int value) {
Value = value;
}
public override string ToString() {
return Value.ToString();
}
}
class TestClass {
Integer _a, _b, _c, _d;
public TestClass(Integer a, Integer b, Integer c, Integer d) {
_a = a;
_b = b;
_c = c;
_d = d;
}
public void Work() {
_a.Value = 111;
_b.Value = 222;
_c.Value = 333;
_d.Value = 444;
}
}
所以現在您有了一個Integer-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/zh-cn/library/ms173109.aspx 。 (Int32是一個結構,而您可能需要一個類)
您嘗試做的事情無法完成,因為它不是設計用於這種方式的。 您必須直接將參數輸入Work
方法中,例如
testObj.Work(ref a, ref b, ref c, ref d);
這種現象是由以下原因引起的
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#參考) 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.