C#中按值传递对象引用:为何置null不影响原对象?
C#按值传递对象引用的行为差异解析
示例代码
var test = new TestClass(); SomeMethod(test); Console.WriteLine(test); SomeMethod2(test); Console.WriteLine(test); Console.ReadKey(); void SomeMethod(TestClass a) { a = null; } void SomeMethod2(TestClass a) { a.intThing = 1; } public class TestClass { public int intThing =0; public override string ToString() { return $"{intThing}"; } }
问题
运行上述代码后发现:SomeMethod方法中将参数a置为null并未修改初始的test对象,但SomeMethod2方法中修改a的intThing字段却改变了原test对象。已知是按值传递对象引用,为何置a为null无法作用于原对象?
解答
核心原因是按值传递的是引用的副本,而非引用本身:
- 调用
SomeMethod(test)时,test存储的是堆中TestClass实例的内存地址,这个地址会被复制一份传给参数a。此时test和a是两个独立变量,但指向同一个堆对象。 - 在
SomeMethod里执行a = null,只是把局部变量a里的地址改成null,完全不影响test变量存储的原地址,所以原对象不会有任何变化。 - 而
SomeMethod2里的a.intThing = 1,是通过a里的地址找到堆上的目标对象,直接修改对象的字段值。因为a和test指向同一个对象,所以原test对应的对象字段会被改变。
简单总结:修改引用副本的指向(比如设为null)不会影响原引用;但通过引用副本操作它指向的对象内容,会同步影响原引用指向的对象——因为它们指向的是同一个堆内存实例。
内容的提问来源于stack exchange,提问作者Dragnipur
相关产品推荐
相关产品推荐

