------- WindowsPhone 7手机开发、.Net培训、期待与您交流! -------
public class XInt {
//定义字段
public int iField = 2;
}
public class Starter
{
/// <summary>
/// 引用类型按引用传递会发生什么呢?函数接受局部引用而不是别名。首先,其中一个引用时按值传递的,在被调用函数中,该参数被赋予一个新实例。
/// 然而,因为引用是按值传递的,所以函数退出后,该修改就被丢失了。因此,元是引用(obj)没有改变。
/// </summary>
/// <param name="alias"></param>
public static void MethodA( XInt alias)
{
XInt inner = new XInt();
inner.iField = 5;
alias = inner;
}
public static void MethodB(int paremeter)
{
paremeter += 5;
}
public static void MethodC(ref int i)
{
i += 5;
}
public static void MethodD(XInt xint)
{
xint.iField += 5;
}
public static void MethodE(ref XInt alias)
{
XInt inner = new XInt();
inner.iField = 5;
alias = inner;
}
public static void Main()
{
XInt obj = new XInt();
MethodA(obj);
Console.WriteLine("引用传值{0}", obj.iField);//2
int local = 2;
MethodB(local);
Console.WriteLine("值传递{0}", local);//2(ok)
int var = 2;
MethodC(ref var);
Console.WriteLine("引用传值{0}", var);//7(ok)
XInt xint = new XInt();
MethodD(xint);
Console.WriteLine("引用传值{0}", xint.iField);//7
XInt obj1 = new XInt();
MethodA( ref obj1);
Console.WriteLine("引用传值{0}", obj.iField);//5
Console.ReadKey();
}
}
解决方案:
参数分为: 1. 值参数 2.引用参数
A.值参数在传递时,首先把参数中的值复制一份,存储在栈中。(int类型其实应该不在堆中的,这里不用管)
如下:
可以看到,他们的内存地址是不同的,栈里的内存会在方法退出时被自动释放。
回头看你的代码:
- XInt obj = new XInt();
虽然 obj 是一个引用类型变量,你用new Xint()创建一个类时,obj中保存了这个类在内存中的地址,但调用 public static void MethodA(XInt alias) 时,obj保存的“地址” 将复制给了 alias 变量!!!!(注意obj和alias)
这个时候如果这样操作:alias.iField+= 5 确实是修改的主函数的 obj 。
但如果执行如下代码:
- XInt inner = new XInt();
- inner.iField = 5;
- alias = inner;
虽然修改了 alias 指向 inner ,而且这时假设不退出,访问alias.iField的值,也确实是5, 但别忘记,alias是值参数,是复制而来的,是在栈中开辟的一块内存保存,方法结束时alias的内存被释放,好像下面的这个样子:
MethodA
{
}
执行到大括号结束时,系统会释放横线上面的内存区域。
---------------------------------------------------------------------------------------------------
假设采用引用传递,这时候,C#将不会复制obj的值,而会直接使用的原来的地址。现在修改了obj中的"地址",就相当于让obj指向了新的地方~!!!