C# 中的类、结构和记录概述

在 C# 中,某个类型(类、结构或记录)的定义的作用类似于蓝图,指定该类型可以进行哪些操作。 从本质上说,对象是按照此蓝图分配和配置的内存块。 本文概述了这些蓝图及其功能。 本系列的下一篇文章介绍对象。

封装

封装有时称为面向对象的编程的第一支柱或原则。 类或结构可以指定自己的每个成员对外部代码的可访问性。 可以隐藏不得在类或程序集外部使用的方法和变量,以限制编码错误或恶意攻击发生的可能性。 有关详细信息,请参阅面向对象的编程教程。

成员

类型的成员包括所有方法、字段、常量、属性和事件。 C# 没有全局变量或方法,这一点其他某些语言不同。 即使是编程的入口点(Main 方法),也必须在类或结构中声明(使用顶级语句时,隐式声明)。

下面列出了所有可以在类、结构或记录中声明的各种成员。

  • 字段
  • 常量
  • 属性
  • 方法
  • 构造函数
  • 事件
  • 终结器
  • 索引器
  • 运算符
  • 嵌套类型

有关详细信息,请参见成员

可访问性

一些方法和属性可供类或结构外部的代码(称为“客户端代码”)调用或访问。 另一些方法和属性只能在类或结构本身中使用。 请务必限制代码的可访问性,仅供预期的客户端代码进行访问。 需要使用以下访问修饰符指定类型及其成员对客户端代码的可访问性:

可访问性的默认值为 private

继承

类(而非结构)支持继承的概念。 派生自另一个类(称为基类)的类自动包含基类的所有公共、受保护和内部成员(其构造函数和终结器除外)。

可以将类声明为 abstract,即一个或多个方法没有实现代码。 尽管抽象类无法直接实例化,但可以作为提供缺少实现代码的其他类的基类。 类还可以声明为 sealed,以阻止其他类继承。

有关详细信息,请参阅继承多态性

界面

类、结构和记录可以实现多个接口。 从接口实现意味着类型实现接口中定义的所有方法。 有关详细信息,请参阅接口

泛型类型

类、结构和记录可以使用一个或多个类型参数进行定义。 客户端代码在创建类型实例时提供类型。 例如,System.Collections.Generic 命名空间中的 List<T> 类就是用一个类型参数定义的。 客户端代码创建 List<string>List<int> 的实例来指定列表将包含的类型。 有关详细信息,请参阅泛型

静态类型

类(而非结构或记录)可以声明为static。 静态类只能包含静态成员,不能使用 new 关键字进行实例化。 在程序加载时,类的一个副本会加载到内存中,而其成员则可通过类名进行访问。 类、结构和记录可以包含静态成员。 有关详细信息,请参阅静态类和静态类成员

嵌套类型

类、结构和记录可以嵌套在其他类、结构和记录中。 有关详细信息,请参阅嵌套类型

分部类型

可以在一个代码文件中定义类、结构或方法的一部分,并在其他代码文件中定义另一部分。 有关详细信息,请参阅分部类和方法

对象初始值设定项

可以通过将值分配给属性来实例化和初始化类或结构对象以及对象集合。 有关详细信息,请参阅如何使用对象初始值设定项初始化对象

匿名类型

在不方便或不需要创建命名类的情况下,可以使用匿名类型。 匿名类型由其命名数据成员定义。 有关详细信息,请参阅匿名类型

扩展方法

可以通过创建单独的类型来“扩展”类,而无需创建派生类。 该类型包含可以调用的方法,就像它们属于原始类型一样。 有关详细信息,请参阅扩展方法

隐式类型的局部变量

在类或结构方法中,可以使用隐式类型指示编译器在编译时确定变量类型。 有关详细信息,请参阅 var(C# 参考)

记录

C# 9 引入了 record 类型,可创建此引用类型而不创建类或结构。 记录是带有内置行为的类,用于将数据封装在不可变类型中。 C# 10 引入了 record struct 值类型。 记录(record classrecord struct)提供以下功能:

  • 用于创建具有不可变属性的引用类型的简明语法。
  • 值相等性。 两个记录类型的变量在它们的类型和两个记录中每个字段的值都相同时,它们是相等的。 类使用引用相等性,即:如果类类型的两个变量引用同一对象,则这两个变量是相等的。
  • 非破坏性变化的简明语法。 使用 with 表达式,可以创建作为现有实例副本的新记录实例,但更改了指定的属性值。
  • 显示的内置格式设置。 ToString 方法输出记录类型名称以及公共属性的名称和值。
  • 支持记录类中的继承层次结构。 记录类支持继承。 记录结构不支持继承。

有关详细信息,请参阅记录

C# 语言规范

有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。