区别
- 结构体是值类型,类是引用类型。
- 结构体存在栈中,类存在堆中。
- 结构体变量和类对象进行类型传递时,结构体变量进行的就是值传递,而类对象进行的是引用传递,或者说传递的是指针,这样在函数中改变参数值,结构体对象的值是不变的,而类对象的值是变化了。
- 在C#中结构体类型定义时,成员是不能初始化的,这样就导致了,定义结构体变量时,变量的所有成员都要自己赋值初始化。但对于类,在定义类时,就可以初始化其中的成员变量,所以在定义对象时,对象本身就已经有了初始值,你可以自己在重新给个别变量赋值。(注意在C++中,类的定义中是不能初始化的,初始化要放在构造函数中)
- 结构体不能申明无参的构造函数,而类可以。
- 声明了结构类型后,可以使用new运算符创建构造对象,也可以不使用new关键字。如果不使用new,那么在初始化所有字段之前,字段将保持未赋值状态且对象不可用。
- 结构体申明有参构造函数后,无参构造不会被顶掉。
- 结构体不能申明析构函数,而类可以。
- 结构体不能被继承,而类可以。
- 结构体需要在构造函数中初始化所有成员变量,而类随意。
- 结构体不能被静态static修饰(不存在静态结构体),而类可以。
使用情景
结构体:
- 结构体是值类型在栈中,栈的存取速度比堆快,但是容量小,适合轻量级的对象,比如点、矩形、颜色。
- 如果对象是数据集合时,优先考虑接结构体(位置,坐标)
- 在变量传值的时候,希望传递对象的是拷贝,而不是对象的引用地址,这个时候就可以使用结构体。
类:
- 类是引用类型,存储在堆中,堆的容量大,适合重量级的对象,栈的空间不大,大量的对应当存在于堆中。
- 如果对象需要继承和多态特征,用类(玩家、怪物)。
Student类
internal class Student
{
public int age;
public string name;
public Student(int age, string name)
{
this.age = age;
this.name = name;
}
}
测试
static void Main(string[] args)
{
Student stu1 = new Student(18, "小芬");
Student stu2 = new Student(25, "小刚");
stu2 = stu1;
stu1.age = 30;
stu1.name = "小燕";
Console.WriteLine(stu2.age);
Console.WriteLine(stu2.name);
}
因为stu2 = stu1传递的是引用,所以修改stu1指向对象,就是修改stu2指向的对象
结构体Student
struct StudentSt
{
public int age;
public string name;
public StudentSt(int age, string name)
{
this.age = age;
this.name = name;
}
}
测试
static void Main(string[] args)
{
StudentSt stu1 = new StudentSt(18, "小芬");
StudentSt stu2 = new StudentSt(25, "小刚");
stu2 = stu1;
stu1.age = 30;
stu1.name = "小燕";
Console.WriteLine(stu2.age);
Console.WriteLine(stu2.name);
}
对于结构体,stu2 = stu1是值传递,即等价于stu2.age = stu1.age,stu2.name=stu1.name,所以修改stu1的值不能影响stu2,结构体都在内存栈里,都是值传递,如果结构体里有字符串类型,那栈里存储的是对字符串的引用,字符串是常量,一直会在静态存储区里,不能被修改