我知道当我们按值将引用类型传递给方法时,会传递引用的副本。如果您在引用类型内部更改值,这也会更改方法外部的值,所以当我们在C#中按引用传递引用类型时?因为它看起来是一样的。
当您通过值将变量传递给方法时,实际上是将该变量值的副本传递给该方法。由于引用类型的值是该类型所引用的引用,因此当您通过值将引用类型变量传递给方法时,您正在将该引用的副本传递给该方法,因此,如果您在方法内部更改变量的值,也将更改方法外部的值。
当你将新实例分配给引用类型的变量时,你实际上是在说该变量引用了新引用,因为你只传递了值的副本,而不是引用类型的引用,所以你不能将新实例指派给方法内部的变量,而是通过ref
传递引用类型,您正在传递引用类型的引用,因此可以将新实例分配给方法内的变量。
这应该很清楚,因为string
是引用类型
public class Program
{
public static void Main()
{
string s1 = "old value a";
string s2 = "old value b";
Method1(ref s1, s2);
Console.WriteLine(s1); // <-- this is what `ref` can do
Console.WriteLine(s2);
}
public static void Method1(ref string a, string b)
{
a = "new value a";
b = "new value b";
}
}
输出
新值a
旧值b
字符串之外的另一种场景
public class Person
{
public string Name
{
get;
set;
}
}
假设我们有一种创建Person
的方法
版本-1
public static void CreatePerson(Person p, string name)
{
p = new Person(){ Name = name};
}
版本-2
public static void CreatePersonV2(ref Person p, string name)
{
p = new Person(){ Name = name };
}
抛出对象引用异常,因为john仍然引用空
Person john = null;
CreatePerson(john, "John");
Console.WriteLine(john.Name);
但这将起作用,因为我们通过引用超过了david
Person david = null;
CreatePersonV2(ref david, "David");
Console.WriteLine(david.Name);