关于微软文档所述C# class为引用类型的概念理解问询
问题解答
你对class和struct赋值行为的理解完全正确
- 对于
class(引用类型):两个变量存储的都是堆上同一个对象的内存地址,通过任意一个变量修改对象的字段、属性,两个变量的返回结果会同步,因为二者操作的始终是同一个实例。 - 对于
struct(值类型):赋值时会完整复制整个结构体的数据,两个变量各自持有独立的副本,修改其中一个的成员完全不会影响另一个。
你对方法传参的理解存在误区,需要纠正
C#默认所有参数传递都是按值传递,和参数是值类型还是引用类型没有关系,二者的区别仅在于传递的内容不同:
- 传递
struct(值类型)时,按值传递的是整个结构体的完整副本,方法内部对参数的修改完全不会影响方法外的原始变量,这部分和你的理解一致。 - 传递
class(引用类型)时,按值传递的是「引用的副本」,也就是把对象的内存地址复制了一份传给方法,此时存在两种情况:如果你在方法内部仅修改引用指向的对象的成员(比如修改
person.Name),这个修改会同步到方法外的原始变量,因为两个引用指向的还是堆上同一个对象。
如果你在方法内部直接给参数变量本身重新赋值(比如person = new Person()),这个修改不会影响方法外的原始变量,因为你修改的只是复制出来的引用副本,原始变量的引用还是指向原来的对象。 - 只有当你给参数加上
ref/out关键字时,才是真正的按引用传递:此时不管参数是值类型还是引用类型,传递的都是原始变量的引用,你在方法内部给参数本身重新赋值,都会直接修改方法外的原始变量。
示例代码验证引用类型默认传参逻辑
public class Person { public string Name { get; set; } } public void TestMethod(Person p) { // 修改对象成员,外部会同步更新 p.Name = "修改后的名字"; // 给参数本身重新赋值,外部不受影响 p = new Person { Name = "全新的对象" }; } // 调用测试 var originalPerson = new Person { Name = "原始名字" }; TestMethod(originalPerson); Console.WriteLine(originalPerson.Name); // 输出结果为「修改后的名字」,而非「全新的对象」
内容的提问来源于stack exchange,提问作者john jeruel Tiongco
相关产品推荐
相关产品推荐

