You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中string为引用类型,为何无法在扩展方法中修改其值?

问题原因解答

你遇到的这个问题和string的特殊表现没有关系,本质是C#的参数传递规则导致的,和所有引用类型的默认传参行为一致:

  • C#中所有参数默认都是按值传递,不管是值类型还是引用类型。
  • 对于引用类型来说,按值传递时,方法拿到的是「指向堆中对象的引用的副本」:也就是说你扩展方法里的input变量,和外部的test变量是两个完全独立的存储单元,只是初始状态下它们指向堆上的同一个字符串对象。
  • 你在方法内执行input = input.Remove(startingIndex, length);,只是把方法内部的input这个引用副本指向了Remove返回的新字符串对象,完全不会修改外部test变量的指向,自然外部的test值不会变。

你可以换任意其他自定义引用类型做测试,都会得到一样的结果,比如下面的示例:

public class MyClass 
{
    public int Value { get; set; }
}

public static void TestExtension(this MyClass obj)
{
    // 这里修改的只是方法内obj这个引用副本的指向,外部变量不会变
    obj = new MyClass { Value = 2 };
}

// 调用代码
var myObj = new MyClass { Value = 1 };
myObj.TestExtension();
Console.WriteLine(myObj.Value); // 输出还是1

你提到的string不可变特性是另一个概念:它指的是堆上的字符串对象本身一旦创建就无法修改,所以Substring、Remove等方法都只会返回新的字符串对象,而不会改动原对象。这个特性只是决定了你必须给input重新赋值才能拿到修改后的字符串,和你当前遇到的「赋值不影响外部变量」的问题无关。

你自己实现的带ref参数的方案能生效,也刚好印证了上面的逻辑:加了ref之后参数变成按引用传递,方法拿到的是外部变量本身的存储地址,修改方法内的input就会直接同步修改外部变量的指向,自然就生效了。


内容的提问来源于stack exchange,提问作者Taco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 23:27:03