所以我们代码的输出应该是5,对不?重点是任何值类型用这种方式传递进方法都是传递的其一个复制本,同时我们希望原先的变量里的值保持不变。
但是要记住的是,如果我们的值类型是个相当大(占用空间)的东东,例如一个很大的struct,那么对其进行复制操作将是非常耗费时间的。同时栈空间并不是无限大的,就像瓶子从水龙头接水,总是会溢出的哦!struct经常可能会变得很大,因此要小心使用。多大才算大?这就是个大大大的struct咯(有那么大嘛……*(*&@#¥%):
public struct MyStruct
{
long a, b, c, d, e, f, g, h, i, j, k, l, m;
}
{
long a, b, c, d, e, f, g, h, i, j, k, l, m;
}
看看使用这个struct时发生了虾米:
public void Go()
{
MyStruct x = new MyStruct();
DoSomething(x);
}
public void DoSomething(MyStruct pValue)
{
// DO SOMETHING HERE....
}
{
MyStruct x = new MyStruct();
DoSomething(x);
}
public void DoSomething(MyStruct pValue)
{
// DO SOMETHING HERE....
}

这可真是效率低下啊。想像一下,如果有数千个对这个struct的调用,那将会是多恐怖的事情!
那可咋办呢?我的程序就是要用到几千次的嘛?答案就是传递一个对这个值类型的引用而不是值类型本身:
public void Go()
{
MyStruct x = new MyStruct();
DoSomething(ref x);
}
public struct MyStruct
{
long a, b, c, d, e, f, g, h, i, j, k, l, m;
}
public void DoSomething(ref MyStruct pValue)
{
// DO SOMETHING HERE....
}
{
MyStruct x = new MyStruct();
DoSomething(ref x);
}
public struct MyStruct
{
long a, b, c, d, e, f, g, h, i, j, k, l, m;
}
public void DoSomething(ref MyStruct pValue)
{
// DO SOMETHING HERE....
}
这样我们就能避免无效率的分配内存了。

现在我们要小心的问题变成了,如果使用引用传递参数,那么我们操作的就是原来值类型中的值了。也就是说,如果我们改变pValue的值,那么x也跟着变了。看看以下的代码,我们得到的结果将是12345,因为pValue实际上指向的就是x的内容。
public void Go()
{
MyStruct x = new MyStruct();
x.a = 5;
DoSomething(ref x);
Console.WriteLine(x.a.ToString());
}
public void DoSomething(ref MyStruct pValue)
{
pValue.a = 12345;
}Passing Reference Types.
{
MyStruct x = new MyStruct();
x.a = 5;
DoSomething(ref x);
Console.WriteLine(x.a.ToString());
}
public void DoSomething(ref MyStruct pValue)
{
pValue.a = 12345;
}Passing Reference Types.
传递引用类型跟使用引用传递值类型其实基本上差球不多。
如果我们在其中使用值类型:
public class MyInt
{
public int MyValue;
}
{
public int MyValue;
}
并且调用Go方法,MyInt存在于堆上因为其是引用类型:
public void Go()
{
MyInt x = new MyInt();
}
{
MyInt x = new MyInt();
}