如果它们都是引用类型,为什么将字符串传递给方法的行为与 List<object> 不同?

Why passing string to a method behaves unlike List<object> if they are both reference type?

我正在阅读让我停在某行的代码:

List<object> props = new List<object>();
DoWork(param1, param2, props);
//props.Count grew up

我在想改变一个超出其范围的变量需要将其作为outref传递,但后来我意识到除非DoWork方法改变props ] 引用如:

props = new List<object>();

引用将指向同一位置。所以这里不用ref

然后我为 string 类型创建了一个方法:

static void ChangeMe(string str)
{
    str = "W77";
}
public static void Main(string[] args)
{
    string str = "p1";
    ChangeMe(str);
    //str is still "p1"
}

如果促使 List 在其范围之外更改的行为是它的引用类型,为什么 string 如果它没有在被调用方方法中重新分配并且它是像 [=21 这样的引用类型,那么为什么 string 不会更改=]?

原因是因为 string 在 C# 中是一个 不可变的 类型,因此每当你 "change" 它实际上你正在做的是创建一个新的 string 使用新值并引用它。

调用 ChangeMe 时,会创建对同一字符串的新引用。然后在该方法中,您将新引用引用到一个全新的字符串,这不会影响 Main.

中定义的先前字符串
  • 对于为什么 字符串是不可变的,请阅读: Why .NET String is immutable?
  • 另外:What is the difference between a mutable and immutable string in C#?

在函数 ChangeMe 中,您有一个对您传入的对象的引用的本地副本。当您在 str 中存储某些内容时,您基本上用一个新的引用替换了该引用。不变性在这里不起作用,因为您实际上并没有尝试修改 str 引用的对象。因此,您现在在 str 中存储了一个新引用,它指向在您使用字符串文字 "W77" 时由字符串构造函数创建的新对象。正如您所指出的,您可以通过 refout.

在函数范围之外获取它