C#基础学习(八)终章 C#中的结构体
假如你要用数据记录一个人,你觉得要记录些什么,身高,体重,名字等。那两个人呢,他是不是也有这样的特征,那我们是不是就可以用一种数据类型将他们共有的特征提取出来,这就是我们今天讲的结构体。
一、初识结构体
结构体 是一种自定义变量类型 类似枚举需要自己定义
它是数据和函数的集合
在结构体中 可以声明各种变量和方法
作用:用来表现存在关系的数据集合 比如用结构体表现学生 动物 人类等
二、结构体的申明
//1.结构体一般写在namespace语句块中
//2.结构体关键字 struct
//struct 自定义结构体名
//{
// //第一部分
// //变量
// //第二部分
// //构造函数(可选)
// //第三部分
// //函数
//}
//结构体名字 帕斯卡命名法
补充小知识:
①访问修饰符:
修饰结构体中的变量和方法 是否能被外部使用
public 公共的 可以被外部使用
private 私有的 只能在内部使用
默认为私有
这个访问修饰符并不仅仅只适用于结构体,以后我们会更加频繁的在类中运用
②构造函数:
和结构体名字同名的函数,无返回值。
作用:为了将你申明的结构体变量进行初始化。默认也可以不写。
三、结构体的实例
//表现学生数据的结构体
struct Student
{
//修饰结构体中的变量和方法 是否能被外部使用
//public 公共的 可以被外部使用
//private 私有的 只能在内部使用
//默认为私有
//变量
//在结构体中申明的变量不能直接初始化
//变量类型 可以写任意类型 包括结构体 但是不能是自己的结构体
public int age;//年龄
public bool sex;//性别
public int number;//学号
public string name;//姓名
//构造函数
结构体的构造函数
//基本概念
//1.没有返回值
//2.函数名必须和结构体名相同
//3.必须有参数
//4.如果申明了构造函数 那么必须在其中对所有变量数据初始化
//构造函数 一般是用于在外部方便初始化的
public Student(int age,bool sex,int number,string name)
{
//新的关键字 this
//代表自己
this.age = age;
this.sex = sex;
this.number = number;
this.name = name;
}
//函数方法
//表现这个数据结构的行为
//注意 在结构体中的方法 目前不需要加static关键字
public void Speak()
{
//函数中可以直接使用结构体中申明的变量
Console.WriteLine("我的名字是{0},今年{1}",name,age);
}
}
四、使用结构体
static void Main(string[] args)
{
//变量类型 变量名;
Student s1;
s1.age = 1;
s1.sex = false;
s1.number = 1;
s1.name ="梁启超";
s1.Speak();
Student s2 = new Student(18,true,2,"小红");
s2.Speak();
Console.ReadLine();
}
补充小知识:
①:默认构造函数不可重写
struct Student
{
public string Name;
public int Age;
public Student(string name, int age)
{
Name = name;
Age = age;
}
}
// 合法:使用默认构造函数
Student s = new Student();
②:只读结构体(C#7.2+)
用readonly
修饰结构体,确保所有字段为只读:
readonly struct ImmutablePoint
{
public readonly int X;
public readonly int Y;
public ImmutablePoint(int x, int y)
{
X = x;
Y = y;
}
}
结构体的使用注意事项:
-
避免大型结构体
结构体赋值时复制整个值,大型结构体会影响性能。建议结构体大小不超过16字节。 -
不要滥用结构体
适合表示简单的数据结构(如坐标、颜色),复杂逻辑建议使用类。 -
慎用可变结构体
修改结构体会创建副本,可能导致预期外的行为:struct MutableStruct { public int Value; } MutableStruct ms = new MutableStruct { Value = 5 }; ms.Value = 10; // 实际是修改副本,原结构体未变(若通过属性访问)
装箱与拆箱:
-
结构体转换为
object
时会装箱(产生堆分配)
int i = 42;
object obj = i; // 装箱
int j = (int)obj;// 拆箱
③结构体与接口
接口是什么我们后面学到面向对象的时候再讲,现在先记住就行。
结构体可以实现接口,但转换为接口类型时会装箱:
interface IDisplay
{
void Show();
}
struct Point : IDisplay
{
public int X, Y;
public void Show() => Console.WriteLine($"({X}, {Y})");
}
// 使用
Point p = new Point { X=3, Y=4 };
p.Show(); // 无装箱
IDisplay disp = p; // 装箱发生
disp.Show();
总结:结构体的核心优势
- 内存高效:栈分配,无GC开销。
- 数据安全:值类型特性避免意外修改。
- 性能优化:适合小型、高频使用的数据结构。
关键决策点:
✅ 使用结构体:数据小、生命周期短、需要值语义。
✅ 使用类:数据大、需要继承、需要引用语义。