在下面的代码中,我试图从类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
有没有办法让方法改变主程序中的变量值? 谢谢!
答案 0 :(得分: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);
}
}
答案 1 :(得分:3)
最好在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是一个结构,而在你的情况下你可能需要一个类)
答案 2 :(得分:2)
您要做的事情无法完成,因为它不是以这种方式设计的。您必须直接将参数放入Work
方法,例如
testObj.Work(ref a, ref b, ref c, ref d);
答案 3 :(得分: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)。