C#什么是 引用类型?

一、先搞懂:什么是 “引用类型”?(3 分钟入门)

引用类型就像 “快递单”

比如你买了一个手机(数据),快递单上写着收货地址(引用)。别人拿到快递单,不是直接拿到手机,而是按地址找到手机。

  • 手机(数据)→ 存在 “堆” 里(内存的一个区域)
  • 快递单(引用)→ 存在 “栈” 里(内存的另一个区域)

和值类型的区别(一句话分清):

  • 值类型 = 实物(比如手里的硬币,你拿到的就是硬币本身)
  • 引用类型 = 地址(比如快递单,你拿到的是找实物的地址)

为什么要用引用类型?

  • 方便共享数据(多人拿着同一张快递单,能找到同一个手机)
  • 适合存储复杂数据(比如一个人的完整信息:姓名、年龄、地址)
  • 支持继承和多态(让代码更灵活,比如 “学生”“老师” 都是 “人” 的引用类型)

二、引用类型有哪些?(6 大类型全解析)

2.1 类(class)—— 最常用的引用类型

类是引用类型的 “代表”,之前学的Student“学生类”、Animal“动物类” 都是引用类型。

特点

  • 数据存在堆里,变量存的是地址
  • 可以继承和多态(比如 “狗” 类继承 “动物” 类)
  • 能包含字段、方法、属性等复杂成员

例子

 
  

class Person // 类是引用类型

{

public string name;

}

// 使用

Person p1 = new Person(); // p1存的是地址(指向堆里的Person对象)

p1.name = "小明";

Person p2 = p1; // p2和p1存的是同一个地址(指向同一个对象)

p2.name = "小红"; // 修改p2的name,p1的name也会变

Console.WriteLine(p1.name); // 输出“小红”(因为p1和p2指向同一个对象)

关键:多个变量可以指向同一个对象,改一个会影响其他(就像多人共享同一个快递地址,改地址里的东西,所有人看到的都变)。

2.2 接口(interface)—— 引用类型的 “行为规范”

接口就像 “说明书”,只规定必须有哪些功能,不规定怎么实现。

特点

  • 只能定义方法、属性的 “签名”(比如 “必须能跑”,但不说怎么跑)
  • 类可以实现多个接口(一个东西可以符合多个说明书)
  • 接口是引用类型,不能实例化(不能直接new一个接口)

例子

 
  

// 定义接口(说明书:必须能吃饭和睡觉)

interface ICanDo

{

void Eat(); // 只说要吃饭,不说怎么吃

void Sleep();

}

// 实现接口(人类符合这个说明书)

class Person : ICanDo

{

public void Eat() // 具体实现“吃饭”

{

Console.WriteLine("用筷子吃饭");

}

public void Sleep() // 具体实现“睡觉”

{

Console.WriteLine("躺着睡");

}

}

// 使用

ICanDo person = new Person(); // 接口变量指向实现类的对象

person.Eat(); // 输出“用筷子吃饭”

关键:接口让不同的类有统一的功能(比如 “鸟” 和 “飞机” 都实现 “能飞” 接口),方便统一调用。

2.3 数组(Array)—— 引用类型的 “有序列表”

数组就像 “编号的抽屉”,每个抽屉放一个数据,按顺序排列。

特点

  • 虽然存的是值类型数据(比如int),但数组本身是引用类型
  • 长度固定(创建时确定抽屉数量,不能改)
  • 变量存的是数组的地址(不是数据本身)

例子

 
  

int[] arr1 = new int[3]; // 数组是引用类型,arr1存的是地址

arr1[0] = 10;

int[] arr2 = arr1; // arr2和arr1指向同一个数组

arr2[0] = 20;

Console.WriteLine(arr1[0]); // 输出20(因为改的是同一个数组)

关键:数组变量赋值时,传递的是地址(就像复制抽屉的地址,两个地址指向同一个抽屉组)。

2.4 字符串(string)—— 特殊的引用类型

字符串就像 “写死的纸条”,一旦创建就不能改(不可变)。

特点

  • 是引用类型,但行为像值类型(修改时会创建新字符串,不影响原来的)
  • 用双引号表示("abc")
  • 变量存的是字符串的地址,但修改时会换新地址

例子

 
  

string s1 = "hello"; // s1存的是“hello”的地址

string s2 = s1; // s2存的是同一个地址

s2 = "world"; // 给s2赋新值,会创建新字符串,s2指向新地址

Console.WriteLine(s1); // 输出“hello”(s1的地址没变,不受影响)

为什么特殊?

普通引用类型改内容会影响其他变量,但字符串改内容时,会新造一个字符串(就像你改了纸条内容,会换一张新纸条,原来的纸条不变)。

2.5 委托(delegate)—— 引用类型的 “方法指针”

委托就像 “遥控器”,可以指向一个方法,按遥控器就执行对应的方法。

特点

  • 专门用来 “引用方法”(和变量引用对象不同,委托引用的是方法)
  • 可以指向多个方法(一个遥控器控制多个设备)
  • 是引用类型,必须先定义委托类型,再创建实例

例子

 
  

// 定义委托类型(遥控器类型:能控制“无参数、无返回值”的方法)

delegate void MyDelegate();

class TV

{

public void TurnOn() { Console.WriteLine("开电视"); }

public void TurnOff() { Console.WriteLine("关电视"); }

}

// 使用

TV tv = new TV();

MyDelegate remote = tv.TurnOn; // 遥控器指向“开电视”方法

remote(); // 按遥控器,执行开电视(输出“开电视”)

remote += tv.TurnOff; // 遥控器再加上“关电视”方法

remote(); // 按遥控器,先开电视再关电视(输出“开电视”和“关电视”)

关键:委托让方法可以像变量一样传递(比如把 “开电视” 方法传给遥控器,再传给别人)。

2.6 对象(object)—— 所有类型的 “老祖宗”

object 就像 “万能容器”,能装任何类型的数据(值类型、引用类型都能装)。

特点

  • C# 中所有类型的基类(任何东西都能转成 object)
  • 是引用类型,装值类型时会 “装箱”(把值类型打包成引用类型)
  • 适合需要 “不确定类型” 的场景(比如一个方法能接收任何数据)

例子

 
  

object obj1 = "字符串"; // 装引用类型

object obj2 = 123; // 装值类型(会装箱)

object obj3 = new Person(); // 装类对象

// 用的时候需要“拆箱”(转成原来的类型)

int num = (int)obj2; // 把object里的123转成int

关键:万能但麻烦,用的时候要转类型(就像万能插座能插任何插头,但有时需要转接头)。

三、引用类型的共同特点(必记 3 点)

  1. 数据存在堆里,变量存地址

就像快递单(变量)存地址,货物(数据)在仓库(堆)里。

  1. 赋值时传递地址,不是数据

复制变量时,两个变量指向同一个对象(比如复印快递单,两张单指向同一个货物)。

  1. 垃圾回收自动清理

当没有变量指向对象时(没人要的货物),系统会自动删除(不用手动清理内存)。

四、引用类型 vs 值类型(一张表分清)

对比项

引用类型(如类、字符串)

值类型(如 int、struct)

存储方式

变量存地址,数据在堆里

变量直接存数据,在栈里

赋值效果

复制地址,多变量指向同一数据

复制数据,多变量各有一份

内存管理

系统自动回收(垃圾回收)

超出作用域自动释放

适合场景

复杂数据(学生、汽车)

简单数据(数字、布尔值)

例子

class、string、int[]

int、bool、struct

五、常见问题(小白必看)

5.1 字符串是引用类型,为什么修改后原来的不变?

因为字符串是 “不可变” 的引用类型,修改时会创建新字符串,原来的字符串不变(就像改快递单上的地址,原来的地址对应的货物还在)。

5.2 数组是引用类型,那数组里的元素是引用类型还是值类型?

数组本身是引用类型,但元素可以是任何类型:

  • int[]数组里的元素是值类型(int)
  • Person[]数组里的元素是引用类型(Person 对象)
5.3 怎么判断一个类型是引用类型还是值类型?
  • 引用类型:class、interface、string、delegate、array、object
  • 值类型:int、double、bool、char、struct、enum

六、核心知识点总结(3 分钟复习)

  1. 引用类型 = 地址:变量存的是数据的地址,不是数据本身
  1. 6 大引用类型
    • 类(class):复杂数据的容器
    • 接口(interface):行为规范说明书
    • 数组(array):有序列表(本身是引用类型)
    • 字符串(string):不可变的文本
    • 委托(delegate):方法的遥控器
    • 对象(object):万能容器
  1. 关键特点:赋值传地址,多变量可共享数据,系统自动回收内存

记住:遇到引用类型,就想 “快递单和货物” 的关系,理解起来超简单!

你可能感兴趣的:(开发语言,c#,学习,笔记)