class是引用类型,struct是值类型

引用类型在堆上,值类型是内联的。

值类型有全部的值的内容,而引用类型只有一个地址。

值类型总是有一个值,而引用类型指针可以为空。

  1. 为了优化减少体积
  2. 需要传递给c++程序
  3. 当作参数传递

除了以上,尽量用class。

struct选择基准:

●设计上

1. 倾向于“载体”,“容器”的概念

(比如其他对象的副本,部分副本,数据的集合...)

2. 无状态性(或简单状态)

(状态相当于一个处于对象生命周期内的东西,存储了状态,即说明对象一般需维持一个较长生命周期)

3. 不具有复杂功能,逻辑。甚至于没有功能。

(仅包含get/set, ctor/dtor, isvalid...基本功能)

●限制,需求等因素

1,内容短

2,限制:

不需要设为null,不需要做方便的初始化(比如泛型内 out参数)

不需要使用引用修改的便捷性(修改一个,所有引用可见)

不能有继承性

3,频繁构建,销毁

4,c/c++兼容性

看过一些C++的struct和class选择文章,道理差不多,更多的从设计根本上去剖析,还是很不错的,有些思想值得多参考。

也有些属于语言的层面的坑,需要注意,比如非引用类型在C#中的种种限制,比如C++的struct和class具备几乎完全相同性质

虽说C#/C++语言特性不同,但是在设计上,从问题本质出发的思考上,结论应该是是具备较大相似性的。

1、比如如下定义:

    class Student_C{public Student_C(string n, int s) { name = n; score = s; }public string name;public int score;}struct Student_S{public Student_S(string n, int s) { name = n; score = s; }public string name;public int score;}

2、引用类型和值类型相比,在创建对象、赋值等基本操作时,含义完全不同。

    class Program{static void Main(string[] args){Student_C s1 = new Student_C("小明", 80);Student_C s2 = s1;// 以上代码在堆上创建了一个"小明"对象,变量s1和s2都指向这个对象Student_S ss1 = new Student_S("小红", 70);Student_S ss2 = ss1;// 以上代码在栈上创建了 两个 临时对象// ss1和ss2是两个独立的学生对象,只是内容相同}}

当我们认识到,即便对于最基本的创建赋值操作,class和struct都是不同的,就会逐步想清楚它们的区别了。

总的来说,C#的struct是为了加速局部对象的处理,包括创建、运算和销毁。所以只有小且频繁的对象才用struct。

例如,Unity中表示坐标的Vector2、Vector3,表示旋转的Quaternion,适合用struct。

它们有两个特点:数据量相当小,只有8~16个字节;计算坐标时会大量创建和使用临时对象。

在这种情况下,使用struct是最合适的。能够减少GC,赋值操作也方便。

除此以外,大多数情况使用class都是更不错的选择。

最后直接回答题主的问题。

1、有一个创建视图的接口,由于参数很多,因此对参数进行封装,封装的参数应该使用class还是struct?

根据题主的字面意思。由于参数数量不确定(未来还可能添加)、字段类型不统一,不满足struct的优化条件,建议使用class。

2、生成excel配置文件对应的class,配置表中的一行数据应该对应一个class还是struct?

从配置文件中读取的数据,一般都是要长期使用的,不存在频繁创建销毁问题;且每一行的数据量估计在十几字节到几百字节不等。所以很可能不满足struct的优化条件,仍然建议使用class。

C# 中 Struct 和 Class 的区别总结

技术译民

公众号:技术译站,专注IT 技术。一个技术译民的『技术译站』

​关注他

6 人赞同了该文章

翻译自 Manju lata Yadav 2019年6月2日 的博文 《Difference Between Struct And Class In C#》,补充了一些内容和示例。

结构体(struct)是类(class)的轻量级版本。结构体是值类型,可用于创建行为类似于内置类型的对象。

比较

结构体和类共享许多特性,但与类相比有以下局限性。

  • 结构体不能有默认构造函数(无参构造函数)或析构函数,构造函数中必须给所有字段赋值。
  public struct Coords{public double x;public double y;public Coords() //错误,不允许无参构造函数{this.x = 3;this.y = 4;}public Coords(double x) //错误,构造函数中必须给所有字段赋值{this.x = x;}public Coords(double x) //这个是正确的{this.x = x;this.y = 4;}public Coords(double x, double y) //这个是正确的{this.x = x;this.y = y;}}
  • 结构体是值类型,在赋值时进行复制。
  • 结构体是值类型,而类是引用类型。
  • 结构体可以在不使用 new 操作符的情况下实例化。 例如:
  public struct Coords{public double x;public double y;}static void Main(){Coords p;p.x = 3;p.y = 4;Console.WriteLine($"({p.x}, {p.y})");  // 输出: (3, 4)}
  • 结构体不能继承于另一个结构体或者类,类也不能继承结构体。所有结构体都直接继承于抽象类 System.ValueTypeSystem.ValueType 又继承于 System.Object
  • 结构体不能是基类,因此,结构体不能是 abstract 的,且总是隐式密封的(sealed)。
  • 不允许对结构体使用抽象(abstract)和密封(sealed)修饰符,也不允许对结构体成员使用 protected 或 protected internal 修饰符。
  • 结构体中的函数成员不能是抽象的(abstract)或虚的(virtual),重写(override)修饰符只允许重写从 System.ValueType 继承的方法。
  • 结构体中不允许实例属性或字段包含初始值设定项。但是,结构体允许静态属性或字段包含初始值设定项。 例如:
  public struct Coords{public double x = 4; //错误, 结构体中初始化器不允许实例字段设定初始值public static double y = 5; // 正确public static double z { get; set; } = 6; // 正确}
  • 结构体可以实现接口。
  • 结构体可以用作 nullable type(即:Nullable<T> 中的 T),对其赋值 null 值,参考【Nullable<T> Struct

什么时候使用结构体或类?

要回答这个问题,我们应该很好地理解它们的差异。

这样,结构体(struct)只能在确定以下情形时使用:

  • 它在逻辑上表示单个值,比如基本类型(intdouble,等等)。
  • 它是不可变的(immutable)。
  • 它不会频繁地装箱和拆箱。

在所有其他情形,应该将类型定义为类(class)。

结构体示例:

struct Location
{public int x, y;public Location(int x, int y){this.x = x;this.y = y;}
}static void Main()
{Location a = new Location(20, 20);Location b = a;a.x = 100;Console.WriteLine(b.x);
}

输出将是 20。“b” 的值是 “a” 的副本,因此 “b” 不受 “a.x” 更改的影响。但是在类中,输出将是 100,因为变量 “a” 和 “b” 引用同一个对象。


以下为译者补充

结构体实例与类实例

结构体实例的内存在栈(stack)上进行分配,所占用的内存随声明它的类型或方法一起回收。 这就是在赋值时要复制结构体的一个原因。 相比之下,类实例的内存在堆(heap)上进行分配,当对类实例的所有引用都超出范围时,为该类实例分配的内存将由公共语言运行时自动回收(垃圾回收)。

结构体实例的值相等性

两个结构体实例的比较是基于值的比较,而类实例的比较则是对其引用的比较。

若要确定两个结构体实例中的实例字段是否具有相同的值,可使用 ValueType.Equals 方法。 由于所有结构体都隐式继承于 System.ValueType,因此可以直接在其对象上调用该方法,如以下示例所示:

public struct Person
{public string Name;public int Age;public Person(string name, int age){Name = name;Age = age;}
}static void Main()
{Person p1 = new Person("技术译站", 100);Person p2;p2.Name = "技术译站";p2.Age = 100;if (p2.Equals(p1))Console.WriteLine("p2 和 p1 有相同的值。");Console.ReadKey();
}
// 输出: p2 和 p1 有相同的值。

System.ValueType 的 Equals 是使用反射实现的,因为它必须能够确定任何结构体中有哪些字段。 在创建自己的结构体时,重写 Equals 方法可以提供特定于你的类型的高效求等算法。

“基于值的相等”这一点和 C# 9.0 中新增的记录(record) 类型具有相似之处,想了解 C# 9.0 可以查看:欢迎来到 C# 9.0。

C#中struct和class的使用区别是什么?相关推荐

  1. C与C++中struct及C++中struct与class的区别

    C++中struct与class的区别 struct class 备注 成员函数 能 能 均有构造函数及析构函数 继承性 能 能 多态性 能 能 均有虚函数 默认成员属性 public private ...

  2. c语言中的typedef struct相当于java的一个类?,C ++中'struct'和'typedef struct'之间的区别?...

    在C ++中,之间有什么区别: struct Foo { ... }; 和 typedef struct { ... } Foo; #1楼 您不能对typedef结构使用forward声明. stru ...

  3. golang中struct字段

    golang中struct字段名首字母必须大写,不然json无法解析 golang中struct字段后面json字段要小写或小写加下划线 golang中首字母大写表示共有

  4. 关于readdir返回值中struct dirent.d_type的取值有关问题(转)

    关于readdir返回值中struct dirent.d_type的取值问题 原网页链接 http://www.gnu.org/software/libc/manual/html_node/Direc ...

  5. C++中struct和class关键字的区别

    文章目录 1 C++中struct和class关键字的区别 1.1 类的关键字 1 C++中struct和class关键字的区别 1.1 类的关键字 C++中类的关键字: struct在C语言中已经有 ...

  6. C++中Struct和Class的区别

    Struct和Class的区别 今天这篇博文主要讲解在C++中关键字struct和class的区别.这篇博文,将会系统的将这两个关键字的不同面进行详细的讲解. 从语法上来讲,class和struct做 ...

  7. [react] react中的setState和replaceState的区别是什么?

    [react] react中的setState和replaceState的区别是什么? setState:更新状态 replaceState:替换状态 个人简介 我是歌谣,欢迎和大家一起交流前后端知识 ...

  8. [react] 解释下react中component和pureComponent两者的区别是什么?

    [react] 解释下react中component和pureComponent两者的区别是什么? 组件的state或者props更新都会触发render(),同时也会导致子组件render()重新渲 ...

  9. C#中struct和class的区别详解

    本文详细分析了C#中struct和class的区别,对于C#初学者来说是有必要加以了解并掌握的. 简单来说,struct是值类型,创建一个struct类型的实例被分配在栈上.class是引用类型,创建 ...

最新文章

  1. 浅谈自然语言处理技术在自动化的应用
  2. 弯曲评论上关于SOC的一段文章【整理】
  3. 02 Java程序员面试宝典视频课程之异常
  4. linux配置环境jdk
  5. 项目中遇到不善于表达的人,该如何沟通?
  6. Artech的MVC4框架学习——第三章controller的激活
  7. HDU - 1757 A Simple Math Problem(矩阵快速幂,水题)
  8. 清除dns缓存命令行_怎么防止移动dns劫持,防止移动dns劫持要先了解什么是dns劫持...
  9. Java 算法 最大体积
  10. ElasticSearch核心基础之映射
  11. 【Java】java LinkedTransferQueue 介绍
  12. 3Dcnn 降假阳性模型调试(八)
  13. 自己收藏整理的一些操作系统资源
  14. 发几个flashxp注册码
  15. 金蝶商贸版密码服务器没显示,金蝶KIS商贸版无损解密用户密码
  16. 计算机图书管理系统测试用例,图书管理系统测试用例设计.doc
  17. Unity3D笔记第十五天——Unity2D技术
  18. 浪潮服务器硬盘阵列怎么做,浪潮智能RAID技术为数据存储保驾护航
  19. c语言程序运行超时是怎么回事,这个运行超时是什么原因?求助~
  20. 文本动画过渡效果AE模板

热门文章

  1. 传统方法 + 深度学习发威! | 2021瓷砖缺陷检测总决赛冠军思路分享
  2. 稳健地估计单应性矩阵,需要几个特征点?
  3. Hi3516ampp编译错误之ls: cannot access '/hiwork/osdrvhi3516a.C02': No such file or directory
  4. JAVA连接SQL Server数据库的端口配置操作步骤
  5. Android类动态加载技术
  6. at24c16如何划分出多个读写区_如何1分钟遍历100T数据?
  7. cent os mysql下载_Cent OS 6.4安装mysql
  8. 吐槽 | 聊一聊公众号的那些事
  9. 腾讯云“抢救”微盟!开 766 次在线会议、调拨 100 多台服务器、闹钟只敢定 2 小时...
  10. 在线作图|如何绘制一张星图