在下面的示例中,"user1"和"user2"指向相同的引用是否正常?
我知道我正在将相同的变量"notUsed"传递给两个参数,但它尚未实例化,因此它不包含对任何内容的引用。看到用户 1 和用户 2 相互链接,我感到非常震惊。
static void CheckPasswords(out string user1, out string user2)
{
user1 = "A";
user2 = "B";
Console.WriteLine("user1: " + user1);
Console.WriteLine("user2: " + user2);
}
public static void Main()
{
string notUsed;
CheckPasswords(out notUsed, out notUsed);
}
控制台显示:
user1: B
user2: B
当您使用out
关键字时,您将通过引用传递。(https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/out-parameter-modifier(由于您是通过引用传递的,因此您的user1
和user2
都指向同一个变量。因此,当您更新一个时,它会更新另一个。
您正在通过引用传递变量。此外,方法中赋值的顺序很重要 - 如此处所述,变量末尾将包含"B"。如果反转它们,则会产生"A"。
比较:
user1 = "A"; // notused now contains "A"
user2 = "B"; // notused now contains "B"
// method ends with the variable notused containing "B"
对:
user2 = "B"; // notused now contains "B"
user1 = "A"; // notused now contains "A"
// method ends with the variable notused containing "A"
这个:
CheckPasswords(out notUsed, out notUsed);
不会将notUsed
的内容传递给方法(就像在不使用out
参数的方法中一样(,它会传递对方法notUsed
的引用。事实上,同样的引用两次。正如你所说,在这一点上,notUsed
本身还没有包含引用,但这并不重要——我们没有对内容做任何事情,事实上,我们不在乎,因为我们把它作为out
传递。然后这个:
user1 = "A";
做一些特别的事情,因为user1
不是一个string
参数 - 它是一个out string
参数。它不是给一些本地user1
赋值,而是给user1
指向的东西赋值——在本例中,notUsed
。此时,notUsed
持有对"A"
的引用。然后这个:
user2 = "B";
做同样的事情,但通过另一个参数 - 它将对"B"
的引用分配给notUsed
。然后是这两行:
Console.WriteLine("user1: " + user1);
Console.WriteLine("user2: " + user2);
检索的不是任何局部变量的内容,而是notUsed
中的值,因为user1
和user2
都指向它。所以,当然,你会得到两次"B"
。
没有比这段代码更令人震惊的了:
class User {
public string Name { get; set; }
}
void NotMagic(User user1, User user2) {
user1.Name = "A";
user2.Name = "B";
Console.WriteLine("user1.Name = " + user1.Name);
Console.WriteLine("user2.Name = " + user2.Name);
}
void Main() {
User user = new User();
NotMagic(user, user);
}
如果这打印B
两次,您可能不会感到惊讶。NotMagic
中有两个不同的参数并不意味着它们不能都指向同一件事。与out
和ref
参数相同,只是语法将为您隐藏额外的间接寻址。