【问题标题】:Why passing string to a method behaves unlike List<object> if they are both reference type? [duplicate]如果它们都是引用类型,为什么将字符串传递给方法的行为与 List<object> 不同? [复制]
【发布时间】:2018-01-05 07:43:40
【问题描述】:

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

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

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

props = new List&lt;object&gt;();

引用将指向相同的位置。所以这里不需要使用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 没有在被调用方方法中重新分配并且它是像 List&lt;object&gt; 这样的引用类型时不会改变?

【问题讨论】:

    标签: c# ref out reference-type


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      原因是因为string 是 C# 中的 不可变 类型,因此每当您“更改”它时,您实际上正在做的是创建一个具有新值的新 string 并引用它.

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-27
        • 2021-09-07
        • 1970-01-01
        • 2014-10-03
        • 2021-12-13
        • 1970-01-01
        相关资源
        最近更新 更多