C# – 通过引用传递参数到构造函数,然后从方法中使用它们

在下面的代码中,我试图从类TestClass中获取一个方法(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 

有没有办法让方法更改主程序中的变量值? 谢谢!

您最好在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/en-us/library/ms173109.aspx 。 (Int32是一个结构,而在你的情况下,你可能需要一个类)

不可能。 您不能将对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); } } 

您要做的事情无法完成,因为它并非旨在以这种方式使用。 您必须直接将参数放入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#Reference) 。