通过引用传递引用

时间:2013-09-06 02:49:19

标签: c# parameter-passing pass-by-reference

通过引用传递引用对象怎么有用呢?常规用法如下:

public static void main()
{
    Student st = new Student();
    st.FirstName = "Marc";
    PutLastName(st);
    Console.WriteLLine(st.FirstName + " " + st.LastName);
}

public static PutLastName(Student student)
{
    student.LastName = "Anthony";
}

为什么有人会写下面的内容,它会做同样的事情并打印出来:" Marc Anthony":

public static void main()
{
    Student st = new Student();
    st.FirstName = "Marc";
    PutLastName(ref st);
    Console.WriteLLine(st.FirstName + " " + st.LastName);
}

public static PutLastName(ref Student student)
{
    student.LastName = "Anthony";
}

3 个答案:

答案 0 :(得分:6)

它没有做同样的事情......在引擎盖下。

从功能上讲,它的工作方式相同,是的。尽管如此......在使用ref时,引用本身正在传递。如果没有ref,则会复制参考值。

将引用视为内存指针。 student的值为1134 ..内存地址。当您不使用ref时,1134将应用于指向相同内存地址的新引用。

当您意识到上述情况时,使用ref会产生危险的后果。例如,考虑一下:

public static void PutLastName(Student student)
{
    student = new Student();
    student.LastName = "Whitehead";
}

// .. calling code ..
Student st = new Student();
st.FirstName = "Marc";
st.LastName = "Anthony";
PutLastName(st);
Console.WriteLLine(st.FirstName + " " + st.LastName); // "Marc Anthony"

然而,使用ref

public static void PutLastName(ref Student student)
{
    student = new Student();
    student.FirstName = "Simon";
    student.LastName = "Whitehead";
}

// .. calling code ..
Student st = new Student();
st.FirstName = "Marc";
st.LastName = "Anthony";
PutLastName(ref st);
Console.WriteLLine(st.FirstName + " " + st.LastName); // "Simon Whitehead"

使用ref物理更改了引用。没有它......你只是告诉不同的引用指向其他地方(一旦函数退出就无效)。因此,当使用ref时,您可以让被调用者物理地更改引用本身...而不仅仅是它指向的内存。

答案 1 :(得分:0)

在第二个版本中,ref表示PutLastName可以更改st。

答案 2 :(得分:0)

通过引用传递引用不仅允许您编辑引用的数据,还允许您更改它所引用的对象。

区别在于这些用途:

// from the Main's point of view, this function does absolutely nothing
public static PutLastName(Student student)
{
    student = new Student();
}

// This would clear Main's student.
public static PutLastName(ref Student student)
{
    student = new Student();
}

请参阅http://msdn.microsoft.com/en-us/library/14akc2c7.aspx