分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

.NET中类和结构的区别

发布时间:2023-09-06 01:43责任编辑:顾先生关键词:.NET

类:
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存
类有构造和析构函数
类可以继承和被继承
结构:
结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。
结构没有构造函数,但可以添加。结构没有析构函数
结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口

结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的(以下摘录):
C#结构体和类的区别问题:在C#编程语言中,类属于引用类型的数据类型,结构体属于值类型的数据类型,这两种数据类型的本质区别主要是各自指向的内存位置不同。传递类的时候,主要表现为是否同时改变了源对象。
C#结构体和类的区别技术要点:
    ◆类在传递的时候,传递的内容是位于托管内存中的位置,结构体在传递的时候,传递的内容是位于程序堆栈区的内容。当类的传递对象修改时,将同时修改源对象,而结构体的传递对象修改时,不会对源对象产生影响。
    ◆在一个类中,可以定义默认的、不带参数的构造函数,而在结构体中不能定义默认的、不带参数的构造函数。两者都可以定义带有参数的构造函数,通过这些参数给各自的字段赋值或初始化
代码运行如下:类中赋值以后,两个对象中的值都发生变化,而结构体原来对象的值为发生变化

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 类对象{ ???//枚举 ?????public enum Gender ???{ ???????男, ???????女 ???} ???//结构体 ???public struct stuPerson ???{ ???????public string stuName; ???????public int stuAge; ???????public Gender stuSex; ???????public void stuSayHello() ???????{ ???????????Console.WriteLine("我是{0},年龄{1},性别{2}", stuName, stuAge, stuSex); ???????} ???????//必须定义有参数的构造函数 ???????public stuPerson(string name, int age, Gender sex) ???????{ ???????????this.stuName = name; ???????????this.stuAge = age; ???????????this.stuSex = sex; ???????} ???} ???class Program ???{ ???????static void Main(string[] args) ???????{ ???????????//实例化类 ???????????Person Liuxiang = new Person(); ?//无参数的构造函数实例化的对象 ???????????Liuxiang.Name = "刘翔"; ???????????Liuxiang.Age = 30; ???????????Liuxiang.Sex = Gender.男; ???????????Liuxiang.SayHello(); ???????????//声明另一个实例 ???????????Person LXSon = Liuxiang; ???????????LXSon.Age = 10; ???????????//查看类 LiuXiang 和 LXSon中字段的值 ???????????Console.WriteLine("LiuXiang 年龄{0}", Liuxiang.Age.ToString()); ?//10 ???????????Console.WriteLine("LXSon 年龄{0}", LXSon.Age.ToString()); ???//10 ???????????Console.WriteLine(); ???????????//结构体 ???????????stuPerson YaoMing = new stuPerson("姚明",33,Gender.男); ???????????YaoMing.stuSayHello(); ???????????stuPerson YMSon = YaoMing; ???????????YMSon.stuAge = 13; ???????????//查看结构体中 YaoMing 和 YMSon中字段的值 ???????????Console.WriteLine("YaoMing 年龄{0}", YaoMing.stuAge.ToString()); ?//10 ???????????Console.WriteLine("YMSon 年龄{0}", YMSon.stuAge.ToString()); ???//10 ???????????Console.ReadLine(); ???????} ???} ???class Person ???{ ???????//定义字段 ???????public string Name; ???????public int Age; ???????public Gender Sex; ???????//定义方法 ???????public void SayHello() ???????{ ???????????Console.WriteLine("我是{0},年龄{1},性别{2}", this.Name, this.Age, this.Sex); ???????} ???????//无参数的构造函数 ???????public Person() ???????{ ???????} ???????//有参数的构造函数 ???????public Person(string name, int age, Gender sex) ???????{ ???????????this.Name = name; ???????????this.Age = age; ???????????this.Sex = sex; ???????} ???}}

总结起来,两者共有如下区别:
1、结构是值类型,类则是引用类型。因此前者是放在栈(Stack)里,后者则仅仅是将引用地址存放在栈里,而具体的值则存放在堆(heap)里。如下图所示:
 
2、据第1点可以得出结论,那就是类对象通常用来传递大数据,而结构对象则用来传递小数据。
3、类可以被继承,而结构则不支持。
4、结构对象不能像类对象一样赋值为null。
5、结构不能像类一样定义析构器。
6、结构不能像类一样定义为抽象的。
7、在结构中不能重写方法,除非是object类型的如下方法:

  1. Equals()
  2. GetHashCode()   
  3. GetType()    
  4. ToString()

若要让结构具有多态特性,可以让其实现接口。
8、在类中定义的事件是线程安全的,而结构则不是。
9、结构总是具有一个默认的公共无参构造函数,但去不能像类一样定义私有的无参构造函数:   

   struct Me ???{ ???????private Me() // compile-time error ???????{ ???????} ???} ???????class Me ???{ ???????private Me() // runs Ok{ ???}

10、类中的静态构造函数会被调用,而结构却不能。因此在结构中定义的静态构造函数,虽然可以编译通过,但却没有价值:    

 ???struct myStructure ???{ ???????static myStructure() ???????{ ???????????Console.WriteLine("This is me a structure"); ???????} ???} ???class myClass ???{ ???????static myClass() ???????{ ???????????Console.WriteLine("This is me a class"); ???????} ???} ???class Program ???{ ???????static void Main(string[] args) ???????{ ??????????myStructure s = new myStructure();//Nothing happen ??????????myClass c = new myClass();//Will out put This is me a class ??????????Console.Read(); ???????} ???}

11、结构不能像类一样定义volatile字段。volatile字段主要用于并发,它相当于方法体的lock。

12、可以对结构类型使用sizeof,对类则不行。
13、类的字段会被自动初始化为0/false/null,而结构则不能。
14、在结构中不能直接对字段初始化,而类则可以。  

 ???struct myStructure ???{ ???????public string x = 2;//Not allowed ???} ???class myClass ???{ ???????public string x = 2; //Allowed ???}

15、结构和类对于System.Object.Equals()方法的体现是不相同的。例如定义这样的结构和类:  

 ????struct StructurePerson ???{ ???????public string FirstName; ???????public string LastName; ???} ???class ClassPerson ???{ ???????public string FirstName; ???????public string LastName; ???}

如果运行如下的代码:   

 ???class Program ???{ ???????static void Main(string[] args) ???????{ ???????????StructurePerson strX = new StructurePerson(); ???????????strX.LastName = "Bejaoui"; ???????????strX.FirstName = "Bechir"; ???????????StructurePerson strY = new StructurePerson(); ???????????strY.LastName = "Bejaoui"; ???????????strY.FirstName = "Bechir"; ???????????if (strX.Equals(strY)) ???????????{ ???????????????Console.WriteLine("strX = strY"); ???????????} ???????????else ???????????{ ???????????????Console.WriteLine("strX != strY"); ???????????}//This code displays strX = strY ???????????ClassPerson clsX = new ClassPerson(); ???????????clsX.LastName = "Bejaoui"; ???????????clsX.FirstName = "Bechir"; ???????????ClassPerson clsY = new ClassPerson(); ???????????clsY.LastName = "Bejaoui"; ???????????clsY.FirstName = "Bechir"; ???????????if (clsX.Equals(clsY)) ???????????{ ???????????????Console.WriteLine("clsX = clsY"); ???????????} ???????????else ???????????{ ???????????????Console.WriteLine("clsX != clsY"); ???????????}//This code displays clsX != clsY ???????????Console.Read(); ???????} ???}
由于结构类型是值类型,因而Equals()方法比较的是两个对象的值是否相等,如果相等则返回true;而类类型为引用类型,Equals()方法比较的是二者的引用地址(即指针)是否相等。很显然,clsX和clsY是两个不同的对象,它们在栈的地址是不相等的。如果修改代码如下: 
ClassPerson clsX = new ClassPerson();clsX.LastName = "Bejaoui";clsX.FirstName = "Bechir";ClassPerson clsY = clsX;if (clsX.Equals(clsY)){ ??Console.WriteLine("clsX = clsY");}else{ ??Console.WriteLine("clsX != clsY");}//This codedisplays clsX = clsY ?

由于是直接将clsX赋值给clsY,因此两个对象的引用地址相等,Equals()方法返回true。 
其实对于值类型和引用类型的相等性比较,是一个比较复杂的问题。例如我们可以通过重写Equals()方法增强或修改比较逻辑。重写Equals()方法还必须重写GetHashCode()方法。对于引用类型,还可以使用静态方法ReferenceEquals()方法。此外,还可以重载操作符==。另外,对于String对象,则比较特殊,因为它使用了Immutable模式。虽然String类型是引用类型,但如果直接定义的两个String对象的值相同,由于采用了Immutable模式的原因,这两个对象其实是同一个对象,引用地址是相同的。因此不仅动态方法Equals()返回的是true,且静态方法ReferenceEquals()返回的也是true

.NET中类和结构的区别

原文地址:https://www.cnblogs.com/vaevvaev/p/8466121.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved