一、结构体和类非常相似

1,定义和使用非常相似,例子如下:
public struct Student
{
    string Name;
    int Age;
}
public class Question
{
    int Number;
     string Content;
}
使用:
Student s=new Student();
Question q=new Question();

2,两者都是container类型,这表示它们可以包含其他数据类型作为成员。
3,两者都拥有成员,包括:构造函数、方法、属性、字段、常量、枚举类型、事件、以及事件处理函数。
4,两者的成员都有其各自的存取范围。例如,可以将某一个成员声明为Public,而将另一个成员声明为Private。
5,两者都可实现接口。
6,两者都可公开一个默认属性,然而前提是这个属性至少要取得一个自变量。
7,两者都可声明和触发事件,而且两者都可以声明委托(Delegate)。

二、结构体和类的区别

总体区别

1,结构体是一种值类型,而类是引用类型。值类型用于存储数据的值,引用类型用于存储对实际数据的引用。那么结构体就是当成值来使用的,类则通过引用来对实际数据操作。
2,结构体的定义是:有些数据既是相互关联的,又共同描述一个完整事物,如:一个学生的整体信息,学号、姓名、性别等。而类则使用在需要比较有层次的数据上面。
3,类是反映现实事物的一种抽象,而结构体的作用只是一种包含了具体不同类别数据的一种包装,结构体不具备类的继承多态特性
4,构造函数是为了初始化类的字段而存在的,而结构体并不需要初始化就能使用,因此,结构体中并不存在默认的构造函数。

结构:
没有默认的构造函数,但是可以添加构造函数
没有析构函数
没有 abstract 和 sealed(因为不能继承)

不能有protected 修饰符
可以不使用new 初始化
在结构中初始化实例字段是错误的

类:

有默认的构造函数
有析构函数
可以使用 abstract 和 sealed
有protected 修饰符
必须使用new 初始化

具体区别如下

1,结构是实值类型(Value Types),而类则是引用类型(Reference Types)。
2,结构使用存储(Stack Allocation),而类使用存储(Heap Allocation)。
3,所有结构成员默认都是Public,而类的变量和常量数则默认位Private,不过其他类成员默认都是Public。
4,结构成员不能被声明位Protected,而类成员可以。

5,结构变量声明不能指定初始值、使用New关键字或对数组进行初始化,但是类变量声明可以。
6,结构不能声明默认的构造函数,也就是不拥有参数的非共享构造函数,但是类则无此限制。
7,二者都可以拥有共享构造函数,结构的共享构造函数不能带有参数,但是类的共享构造函数则可以带或者不带参数。
8,结构不允许声明析构函数(Destructor),类则无此限制。

9, 结构永远不会终止,因此CLR不会在任何结构上调用Finalize方法。类则是由内存回收进程加以终止,当内存回收进程检测到没有任何作用的类时,它就会调用类的Finalize方法。
10,结构的实例(Instance)声明,不允许对包含的变量进行初始化设定,类则可以在声明类的实例时,同时进行变量初始化。

11,结构不需要构造函数,类则需要构造函数。
12,结构是隐式继承自ValueType类,而且不能继承任何其他类型,类则可以继续自ValueType以外的任何类。
13,结构是无法被继承的,类则可以。
14,结构只能在一种情况下使用非共享构造函数,那就是非共享构造函数会接受参数。但是类则无此限制,它可以使用带参数或不带参数的非共享构造函数。
15,每一个结构都具有无参数的隐含公共构造函数,此构造函数会将结构的所有成员初始化为其默认值。不需要重新定义这个行为。

在“实例和变量”层面上,由于结构是数值类型的,因此每一个结构变量会永远的绑定到结构实例上。然而类是引用类型的,而且对象变量可引用不同的类实例,在此方面的区别,会对使用将结构和类造成如下的影响:

16,结构变量会隐式的使用结构的无参数构造函数来初始化成员,这就意味语句 Struct S = new Struct()。
17,当您将一个结构变量赋值给另一个,或者将结构实例传递到程序变量时,所有变量成员的值会复制到新的结构中。当您将一个对象变量赋值给另一个,或者将对象变量传递给程序时,则只是复制指针。
18,您可以将Null值赋值给结构变量,但是该实例会一直与该变量保持关联。虽然变量成员会因此赋值而重新初始化,但是您还是可以调用变量的方法并访问其数据成员。相反的,如果您将对象变量设定为Null,您就会中断它与任何类型实例的关联,而且除非您再将另一个实例赋值给它,否则无法通过变量访问任何成员。
19,您可以在不同时间将不同的类的实例赋值给同一个对象变量,而且在同一时间可有好几个对象变量引用相同的类实例,如果您对类成员值做了改变,则其他指向相同实例的对象变量也会发生改变。然而,结构成员则会封装在他们自己的实例中,变更结构成员值并不会对其他任何结构变量的成员造成影响,甚至也不会影响相同结构声明的其他实例。
20,两个结构必须以成员对成员的比较方式来执行相等比较。两个对象变量可以使用Equals方法来加以比较。Equals会判断两个变量是否指向相同的实例。

三.设计时该如何选择

1.  堆栈的空间有限,对于大量的逻辑的对象,创建类要比创建结构好一些
2.  结构表示如点、矩形和颜色这样的轻量对象,例如,如果声明一个含有 1000 个点对象的数组,则将为引用每个对象分配附加的内存。在此情况下,结构的成本较低。
3.  在表现抽象和多级别的对象层次时,类是最好的选择
4.  大多数情况下该类型只是一些数据时,结构时最佳的选择

参考文章

结构体和类的区别

C#中结构体与类的区别的更多相关文章

  1. C#中结构体和类的区别

    结构体和类同样能够定义字段,方法和构造函数,都能实例化对象,这样看来结构体和类的功能好像是一样的了,但是他们在数据的存储上是不一样的 C#结构体和类的区别问题:这两种数据类型的本质区别主要是各自指向的 ...

  2. C++中结构体与类的区别 2

    这里有两种情况下的区别.(1)C的struct与C++的class的区别.(2)C++中的struct和class的区别.在第一种情况下,struct与class有着非常明显的区别.C是一种过程化的语 ...

  3. C++中结构体与类的区别(结构不能被继承,默认是public,在堆栈中创建,是值类型,而类是引用类型)good

    结构是一种用关键字struct声明的自定义数据类型.与类相似,也可以包含构造函数,常数,字段,方法,属性,索引器,运算符和嵌套类型等,不过,结构是值类型. 1.结构的构造函数和类的构造函数不同. a. ...

  4. C++中结构体与类的区别(struct与class的区别)

    转载来源:http://blog.sina.com.cn/s/blog_48f587a80100k630.html C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据 ...

  5. C++中结构体与类的区别 1

    转载来源:http://blog.sina.com.cn/s/blog_48f587a80100k630.html C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据 ...

  6. [转]C#中的结构体与类的区别

    C#中的结构体与类的区别   经常听到有朋友在讨论C#中的结构与类有什么区别.正好这几日闲来无事,自己总结一下,希望大家指点. 1. 首先是语法定义上的区别啦,这个就不用多说了.定义类使用关键字cla ...

  7. C C++ 中结构体与类

    先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...

  8. C#结构体和类的区别(转)

    结构体和类的区别:    在做一个项目时,使用了较多的结构体,并且存在一些结构体的嵌套,即某结构体成员集合包含另一个结构体等,总是出现一些奇怪的错误,才终于下决心好好分析一下到底类和结构体有啥不同,虽 ...

  9. C++中 结构体和类的异同

    在C++中,结构体是一种特殊形态的类. 结构体和类的唯一区别就是:  结构体和类具有不同的默认访问控制属性. 类中,对于未指定访问控制属性的成员,其访问控制属性为私有类型(private) 结构体中, ...

随机推荐

  1. Spring MVC 使用 HttpServletResponseWrapper 修改返回结果

    HttpServletResponseWrapper 是什么? ServletResponse 的包装类,相关设计模式 装饰者模式. 运行环境 jdk 1.7 spring boot 整合的web环境 ...

  2. log4j2用Log4jContextSelector启动参数配置全局异步日志是如何使用disruptor

    与 log4j2用asyncRoot配置异步日志是如何使用disruptor差异有几个: 给disruptor实例的EventFactory不同 此处EventFactory采用的是RingBuffe ...

  3. jmeter将上一个请求的结果作为下一个请求的参数——使用正则提取器

    转自:http://www.cnblogs.com/0201zcr/p/5089620.html 在压力测试的时候,经常要将几个流程串联起来才能将程序测试通过.如:我现在用户首先要登录,获得我登录的凭 ...

  4. [转]Ubuntu下添加开机启动脚本

    作者: 王恒 发表于 2012年 11月 5日 1.方法一,编辑rc.loacl脚本 Ubuntu开机之后会执行/etc/rc.local文件中的脚本, 所以我们可以直接在/etc/rc.local中 ...

  5. PDF文件加密怎么转换成word

    1.将文档拖入Chrome浏览器 2. 3.右上角打印,然后会提示 另存为本地,然后再用word或者福昕套件转换就行

  6. UVA11806 Cheerleaders (容斥)

    题目链接 Solution 可以考虑到总方案即为 \(C_{nm}^k\) . 考虑到要求的是边缘都必须至少有 \(1\) ,所以考虑不合法的. 第一行和最后一行没有的方案即为 \(C_{(n-1)m ...

  7. JavaScript Array 对象的方法,比如push和unshift

    https://www.runoob.com/jsref/jsref-obj-array.html js数组与字符串的相互转换 一.数组转字符串 需要将数组元素用某个字符连接成字符串,示例代码如下: ...

  8. 基于webpack搭建vue-cli以及webstorm的设置

    N1.检查本地电脑是否安装node和npm 安装vue-cli的前提是已经安装了npm 是否安装npm检查命令 npm -v 如果出现版本号,说明已经安装了npm 查看node版本号 node -v ...

  9. redux使用需要注意的地方

    1. react和redux没有直接联系,当react需要结合redux使用的时候,需要引入 react-redux ,该插件提供了connet等方法使得react可以注入redux属性. 2. re ...

  10. Lis(bzoj 3532)

    Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序列长度减少至少1,且付出的代价之和最小,并输出方案.    如果有多种方案,请输出 ...