通过引用传递引用

yaz*_*pro 2 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";
}
Run Code Online (Sandbox Code Playgroud)

为什么有人会写下面的内容,它会做同样的事情并打印出来:"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";
}
Run Code Online (Sandbox Code Playgroud)

Sim*_*ead 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"
Run Code Online (Sandbox Code Playgroud)

然而,使用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"
Run Code Online (Sandbox Code Playgroud)

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