按值传递时,传递过去的是该引用类型实例的引用的一个拷贝,这样说可能不是很清楚,而且容易引起误解。所谓引用,就是分配在栈上的一小块内存区域,里面存放着该引用类型实例在托管堆上的地址。引用类型在按值传递的时候,其实就是把它的引用在栈上复制出来一份,然后传递给方法。这样就造成了栈上的两个引用指向了托管堆上的同一个实例。所以这就可以解释,如下两个方法运行结果为什么会不一致。
class Person
{
public string Name { get; set; }
}
......
static void ChangePerson(Person person)
{
person = new Person();
person.Name = "Changing Name";
Console.WriteLine(person.Name);
}
static void ChangeName(Person person)
{
person.Name = "Changing Name";
Console.WriteLine(person.Name);
}
......
// 引用类型的按值传递
Person person = new Person() { Name="Old" };
ChangeName(person);
Console.WriteLine(person.Name);
// 引用类型的按值传递 person = new Person() { Name = "Old" };
ChangePerson(person);
Console.WriteLine(person.Name);
运算结果如下:
实战:
如下代码必须使用ref,因为在RefreshTimerControl方法中lastTimerConrtol= nowTimerControl; 等于lastTimerConrtol重新指向了托管堆上的另外一个实例,因此在RefreshTimerControl方法执行后 mUpTime还是null。
//稼动率
mUpTime=null;
RefreshTimerControl(ref mUpTime, StringHelper.UpTime);
private void RefreshTimerControl(ref TimerControl lastTimerControl, string nowTimerControlName)
{
lastTimerControl = nowTimerControl;
}