C# 快速操作和重构
Visual Studio Code 提供了多种重构源代码的方法,以及在编码时生成代码和修复问题的快速修复功能。要访问它们,请单击出现的“灯泡”图标,或使用 快速修复 命令 ⌘. (Windows, Linux Ctrl+.) 显示快速修复和重构选项列表。您也可以右键单击编辑器并选择 重构 ⌃⇧R (Windows, Linux Ctrl+Shift+R) 以仅显示重构选项。
支持的重构和快速修复
- 添加
await - 从成员添加构造函数参数
- 添加
DebuggerDisplay属性 - 添加显式转换
- 添加文件头
- 添加缺少的
usings/ 导入 - 添加命名参数
- 将匿名类型转换为类
- 在自动属性和完整属性之间转换
- 在直接转换和
as表达式之间转换 - 在
for循环和foreach语句之间转换 - 在 Get 方法和属性之间转换
- 在
if和switch语句之间转换 - 在常规字符串和逐字字符串之间转换
- 将类转换为记录
- 将局部函数转换为方法
- 将数字字面量转换为十六进制、十进制或二进制数
- 将占位符转换为插值字符串
- 将常规字符串转换为插值字符串
- 将元组转换为结构体
- 封装字段
- 生成比较运算符
- 生成默认构造函数
- 生成参数
- 显式实现所有成员
- 隐式实现所有成员
- 内联方法
- 内联临时变量
- 为表达式引入局部变量
- 引入参数
- 引入
using语句 - 反转条件表达式和逻辑运算
- 反转
if - 使成员静态化
- 将声明移至引用附近
- 将类型移至匹配文件
- 反转
for语句 - 拆分或合并
if语句 - 使用显式类型
- 使用隐式类型
- 使用 Lambda 表达式或块体
- 使用递归模式
- 包装、缩进和对齐重构
添加 await
作用:将 await 关键字添加到函数调用。
时机:在异步方法中调用函数时。
操作方法
- 将插入符放在函数调用旁边(很可能显示红色下划线)。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 添加
await。

从成员添加构造函数参数
作用:根据选定的类成员生成一个带参数的新构造函数。
时机:您引入了一个新构造函数,并希望自动正确声明所有正确的参数。
原因:您可以在使用构造函数之前声明它,但是此功能会自动生成它。
操作方法
- 突出显示要作为参数添加到构造函数中的类成员。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 生成构造函数 <classname>(<membertype>, <membertype>, <etc.>)。

添加 DebuggerDisplay 属性
作用:DebuggerDisplay 属性 控制对象、属性或字段在调试器变量窗口中的显示方式。
时机:您希望在代码中以编程方式固定属性。
原因:固定属性允许您通过将该属性置于调试器中对象属性列表的顶部来快速检查对象的属性。
操作方法
- 将光标置于类型、委托、属性或字段上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单,然后选择 添加
DebuggerDisplay属性。 DebuggerDisplay属性将与返回默认ToString()的自动方法一起添加。

添加显式转换
作用:允许您根据用法自动向表达式添加显式转换。
时机:您需要向表达式添加显式转换并希望自动正确分配它。
原因:您可以手动向表达式添加显式转换,但是此功能会根据代码上下文自动添加它。
操作方法
- 将插入符放在错误处。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 添加显式转换。
添加文件头
作用:使用 EditorConfig 将文件头添加到现有文件、项目和解决方案。
时机:您希望轻松地将文件头添加到文件、项目和解决方案。
原因:您的团队要求您出于版权目的包含文件头。
操作方法
- 如果您的项目或解决方案中没有 EditorConfig,请添加一个。
- 将以下规则添加到您的 EditorConfig 文件中:
file_header_template。 - 将规则的值设置为您希望应用的标题文本。您可以使用
{fileName}作为文件名的占位符。 - 将插入符放在任何 C# 文件的第一行。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 添加文件头。
添加缺少的 using / 导入
作用:允许您立即为复制粘贴的代码添加必要的导入或 using 指令。
时机:从项目中的不同位置或其他来源复制代码并将其粘贴到新代码中是常见做法。此快速操作会查找复制粘贴代码中缺少的导入指令,然后提示您添加它们。此代码修复还可以添加项目到项目的引用。
原因:由于快速操作会自动添加必要的导入,因此您无需手动复制代码所需的 using 指令。
操作方法
- 从一个文件复制代码并将其粘贴到新文件中,但不包含必要的 using 指令。生成的错误将附带一个代码修复,该修复会添加缺少的 using 指令。
- 选择 ⌘. (Windows, Linux Ctrl+.) 以打开 快速操作和重构 菜单。
- 选择 Using <您的引用> 以添加缺少的引用。

添加命名参数
作用:将命名参数附加到函数调用中指定的参数值。
时机:如果您的方法有大量参数,您可以添加命名参数以使代码更具可读性。
操作方法
- 将光标放在函数调用中的参数内。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 添加参数名 <parameter name>。

将匿名类型转换为类
作用:将匿名类型转换为类。
时机:您有一个匿名类型,希望在类中继续构建它。
原因:如果只在本地使用匿名类型,它们会很有用。随着代码的增长,有一个简单的方法将它们提升为类会很方便。
操作方法
- 将光标放在匿名 (
var) 类型中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 转换为类。

在自动属性和完整属性之间转换
作用:在自动实现的属性和完整属性之间进行转换。
时机:属性的逻辑已更改。
原因:您可以手动在自动实现的属性和完整属性之间进行转换,但此功能将自动为您完成这项工作。
操作方法
- 将光标放在属性名称上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下两个选项中选择
选择 转换为完整属性。

选择 使用自动属性。

在直接转换和 'as' 表达式之间转换
作用:使用 as 关键字在常规转换和尝试转换之间转换变量。
时机:当您预计在某些情况下转换会失败 (as) 或您从不预计转换会失败 (直接转换) 时。
操作方法
- 将光标放在变量上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下两个选项中选择
选择 更改为转换。

选择 更改为 as 表达式。

在 for 循环和 foreach 语句之间转换
作用:如果您的代码中有 for 循环,您可以使用此重构将其转换为 foreach 语句。
原因:您可能希望将 for 循环转换为 foreach 语句的原因包括
- 除了作为访问项的索引,您不在循环内部使用局部循环变量。
- 您希望简化代码并减少初始化器、条件和迭代器部分中逻辑错误的 L可能性。
您可能希望将 foreach 语句转换为 for 循环的原因包括
- 您希望在循环内部使用局部循环变量,而不仅仅是访问项。
- 您正在迭代多维数组,并且希望更好地控制数组元素。
操作方法
- 将插入符放在
foreach或for关键字中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下两个选项中选择
选择 转换为 for。

选择 转换为 foreach。

在 Get 方法和属性之间转换
将 Get 方法转换为属性
作用:允许您将 Get 方法转换为属性(可选地,您的 Set 方法)。
时机:您有一个不包含任何逻辑的 Get 方法。
操作方法
- 将光标放在 Get 方法名称中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- (可选) 如果您有一个 Set 方法,您也可以此时转换您的 Set 方法。选择 将 <Get 方法或 Set 方法名称> 替换为属性。

将属性转换为 Get 方法
作用:允许您将属性转换为 Get 方法
时机:您有一个涉及不仅仅是立即设置和获取值的属性
操作方法
- 将光标放在 Get 方法名称中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 将 <属性名称> 替换为方法。

在 if 和 switch 语句之间转换
作用:将 if 语句转换为 switch 语句 或 C# 8.0 switch 表达式。
时机:您希望将 if 语句转换为 switch 语句或 switch 表达式,反之亦然。
原因:如果您正在使用 if 语句,此重构可以轻松转换为 switch 语句或 switch 表达式。
操作方法
- 将光标放在
if关键字中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择
选择 转换为 switch 语句。

选择 转换为 switch 表达式。

选择 转换为 if 语句。

在常规字符串和逐字字符串之间转换
作用:允许您在常规字符串和逐字字符串字面量之间进行转换。
时机:您希望节省空间或使代码更清晰。
原因:将逐字字符串字面量转换为常规字符串字面量有助于节省空间。将常规字符串字面量转换为逐字字符串字面量可以提供更清晰的表达。
操作方法
- 将插入符放在常规字符串或逐字字符串字面量上
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择一个
选择 转换为常规字符串。
选择 转换为逐字字符串。
将类转换为记录
作用:将您的类转换为 C# 记录。
时机:当您想快速将类更改为记录时,记录是为存储数据和不变性量身定制的。
操作方法
- 将光标放在类名上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 转换为位置记录。


将局部函数转换为方法
作用:将局部函数转换为方法。
时机:您有一个局部函数,希望在当前局部上下文之外定义它。
原因:您希望将局部函数转换为方法,以便可以在局部上下文之外调用它。当您的局部函数变得太长时,您可能希望转换为方法。当您在单独的方法中定义函数时,您的代码更容易阅读。
操作方法
- 将光标放在局部函数中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 转换为方法。

将数字字面量转换为十六进制、十进制或二进制数
作用:在十六进制、二进制或十进制数之间转换数字。
时机:当您希望自动将数字转换为所需基数而无需手动计算转换时使用。
操作方法
- 将光标放在数字字面量上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择以下选项之一
选择 转换为十进制。

选择 转换为十六进制。

选择 转换为二进制。

将占位符转换为插值字符串
作用:将 String.Format 格式化结果字符串(或占位符)转换为插值字符串。
时机:当您想快速获得插值字符串时使用。
原因:插值字符串可以为您提供更易读的 String.Format 版本,并且可以直接访问变量名。
操作方法
- 将光标放在
String.Format占位符上。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 转换为插值字符串。

将常规字符串转换为插值字符串
作用:将常规字符串更改为插值字符串。
时机:当您希望清理代码并使其更具可读性时使用。
操作方法
- 将光标放在要转换的字符串上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 转换为插值字符串。


将元组转换为结构体
作用:将元组转换为 struct
时机:当您想快速将元组更改为 struct 并希望拥有可以多次访问的固定数据时使用。
操作方法
-
将光标放在元组上。
-
按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
-
选择以下选项之一
- 选择 转换为
struct-> 更新包含成员中的用法 - 选择 转换为
struct-> 更新包含类型中的用法 - 选择 转换为
struct-> 更新包含项目中的用法 - 选择 转换为
struct-> 更新依赖项目中的用法
- 选择 转换为


封装字段
作用:允许您将字段转换为属性,并更新该字段的所有用法以使用新创建的属性。
时机:您希望将字段移入属性,并更新对该字段的所有引用。
原因:您希望授予其他类访问字段的权限,但又不希望这些类直接访问。通过将字段包装在属性中,您可以编写代码来验证正在分配的值,例如。
操作方法
- 将光标放在要封装的字段名称内。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择以下选项之一
选择 封装字段:<字段名>(并使用属性)。

选择 封装字段:<字段名>(但仍使用字段)。

生成比较运算符
作用:允许您为实现 IComparable 的类型生成比较运算符。
时机:当您有一个实现 IComparable 的类型时,我们将自动添加比较运算符。
原因:如果您正在实现值类型,则应考虑重写 Equals 方法,以获得比 ValueType 上 Equals 方法的默认实现更高的性能。
操作方法
- 将光标放在类内或 IComparable 关键字上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从下拉菜单中选择 生成比较运算符。
生成默认构造函数
作用:允许您立即为类上的新默认构造函数生成代码。
时机:您引入了一个新的默认构造函数,并希望自动正确声明它。
原因:您可以在使用构造函数之前声明它,但是此功能会自动生成它。
操作方法
- 将光标放在类名上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 生成构造函数 <classname>()。

生成参数
作用:自动生成方法参数。
时机:您在方法中引用了当前上下文中不存在的变量并收到错误;您可以生成参数作为代码修复。
原因:您可以快速修改方法签名而不会丢失上下文。
操作方法
- 将光标放在变量名中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 生成参数。

显式实现所有成员
作用:在类中显式定义接口的方法。显式接口实现是只能通过指定接口调用的类成员。
时机:在以下情况下使用
- 您不希望对多个接口调用相同的实现。
- 您希望解决两个接口各自声明相同名称的不同成员(例如属性和方法)的情况。
操作方法
- 将光标放在类中正在实现的接口上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 显式实现所有成员

隐式实现所有成员
作用:在类中隐式定义接口的方法。隐式接口实现是指接口的方法和属性直接作为公共方法添加到类中。
操作方法
- 将光标放在类中正在实现的接口上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 实现接口

内联方法
作用:内联方法重构。
时机:您希望将单个语句主体中静态、实例和扩展方法的用法替换为可选地删除原始方法声明。
原因:此重构提供了更清晰的语法。
操作方法
- 将插入符放在方法的用法上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择一个
选择 内联 <QualifiedMethodName> 以删除内联方法声明

选择 内联并保留 <QualifiedMethodName> 以保留原始方法声明

内联临时变量
作用:允许您删除临时变量并将其替换为其值。
时机:临时变量的使用使代码难以理解。
原因:删除临时变量可以使代码更易于阅读。
操作方法
- 将光标放在要内联的临时变量内。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 内联临时变量。

为表达式引入局部变量
作用:允许您立即生成局部变量以替换现有表达式。
时机:您的代码如果在一个局部变量中,以后可以轻松重用。
原因:您可以多次复制和粘贴代码以在不同位置使用它,但是最好执行一次操作,将结果存储在局部变量中,并在整个代码中使用局部变量。
操作方法
- 将插入符放在要分配给新局部变量的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择
选择 引入局部变量 -> 为 <expression> 引入局部变量

选择 引入局部变量 -> 为 <expression> 的所有出现引入局部变量
引入参数
作用:允许您立即生成新参数以替换现有表达式。
时机:您的代码如果在一个参数中,以后可以轻松重用。
原因:您可以多次复制和粘贴代码以在不同位置使用它,但是最好执行一次操作,将结果存储在参数中,并在整个代码中使用参数。
操作方法
- 将插入符放在要分配给新参数的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择
选择 为 <expression> 引入参数 -> 并直接更新调用点

选择 为 <expression> 引入参数 -> 到提取的方法中

选择 为 <expression> 引入参数 -> 到新重载中

引入 using 语句
作用:向您的 IDisposable 实例添加 using 语句 / 代码块。
时机:您有一个 IDisposable 实例,希望确保其正确获取、使用和处置。
操作方法
- 将插入符放在要分配给新参数的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 引入
using语句。

反转条件表达式和逻辑运算
作用:允许您反转条件表达式或条件 and \ or 运算符。
时机:您有一个条件表达式或条件 and \ or 运算符,如果反转,会更容易理解。
原因:手动反转表达式或条件 and \ or 运算符可能需要更长时间,并可能引入错误。此代码修复帮助您自动执行此重构。
操作方法
- 将光标放在条件表达式或条件
and\or运算符中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 反转条件 或 将
&&替换为||


反转 if
作用:允许您反转 if 或 if else 语句而不改变代码的含义。
时机:当您有一个 if 或 if else 语句,反转后会更容易理解时。
原因:手动反转 if 或 if else 语句可能需要更长时间,并可能引入错误。此代码修复帮助您自动执行此重构。
操作方法
- 将光标放在
if或if else语句中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 反转
if。

使成员静态化
作用:使成员静态化。
时机:您希望将非静态成员设置为静态。
原因:静态成员提高了可读性:了解特定代码是隔离的,使其更容易理解、重读和重用。
操作方法
- 将插入符放在成员名称上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 设为静态。

将声明移至引用附近
作用:允许您将变量声明移至其使用位置附近。
时机:您有可以在更窄范围内使用的变量声明。
原因:您可以保持原样,但这可能会导致可读性问题或信息隐藏。这是一个重构以提高可读性的机会。
操作方法
- 将光标放在变量声明中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 将声明移至引用附近。

将类型移至匹配文件
作用:允许您将选定的类型移动到具有相同名称的单独文件中。
时机:您在同一个文件中包含多个类、结构、接口等,希望将它们分开。
原因:将多个类型放在同一个文件中会使其难以找到这些类型。通过将类型移动到具有相同名称的文件中,代码变得更具可读性且更易于导航。
操作方法
- 将光标放在类型定义名称的内部。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 将类型移动到 <typename>.cs。

反转 for 语句
作用:允许您反转 for 语句。
时机:当您想反转 for 语句的含义及其迭代方式时使用。
原因:手动反转 for 语句可能需要更长时间,并可能引入错误。此代码修复帮助您自动执行此重构。
操作方法
- 将光标放在
for语句中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 反转
for语句。

拆分或合并 if 语句
作用:拆分或合并 if 语句。
时机:您希望将使用 && 或 || 运算符的 if 语句拆分为嵌套 if 语句,或将 if 语句与外部 if 语句合并。
原因:这只是风格偏好问题。
操作方法
如果您想拆分 if 语句
- 将光标放在
if语句中&&或||运算符旁边。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 拆分为嵌套
if语句。

如果您想将内部 if 语句与外部 if 语句合并
- 将光标放在内部
if关键字中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 与嵌套
if语句合并。

使用显式类型
作用:使用此重构将局部变量声明中的 var 替换为显式类型。
原因:为了提高代码的可读性,或者当您不想在声明中初始化变量时。
但是,当变量使用匿名类型初始化并且对象的属性在稍后访问时,必须使用 var。有关详细信息,请参阅隐式类型局部变量 (C#)。
操作方法
- 将插入符放在
var关键字上。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 使用显式类型而不是
var。

使用隐式类型
作用:使用此重构将局部变量声明中的显式类型替换为 var。
原因:为了符合您的个人编码约定并减少代码显示。当变量使用匿名类型初始化并且对象的属性在稍后访问时,必须使用 Var。有关详细信息,请参阅隐式类型局部变量 (C#)。
操作方法
- 将插入符放在显式类型关键字上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 使用隐式类型。

使用 Lambda 表达式或块体
作用:允许您重构 Lambda 表达式以使用表达式主体或块主体。
时机:您更喜欢 Lambda 表达式使用表达式主体或块主体。
原因:可以根据您的用户偏好重构 Lambda 表达式以提高可读性。
操作方法
- 将光标放在 Lambda 运算符的右侧。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择以下选项之一
选择 Lambda 表达式使用块主体。

选择 Lambda 表达式使用表达式主体。

使用递归模式
作用:将代码块转换为使用递归模式。此重构适用于 switch 语句、属性模式匹配、元组模式匹配和位置模式匹配。
时机:使用递归模式可以使您的代码更具可读性/更简洁。
操作方法
- 将光标放在要转换为递归模式的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择以下选项之一
选择 将 switch 语句转换为表达式。

选择 使用递归模式。


包装、缩进和对齐重构
包装并对齐调用链
作用:允许您包装和对齐方法调用链。
时机:您的一个语句中有一个由多个方法调用组成的很长的链。
原因:根据用户偏好,在包装或缩进后阅读长列表更容易。
操作方法
- 将光标放在任何调用链中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 包装调用链 或 包装并对齐调用链 以接受重构。

包装、缩进和对齐参数或实参
作用:允许您包装、缩进和对齐参数或实参。
时机:您的方法声明或调用有多个参数或实参。
原因:根据用户偏好,在包装或缩进后阅读长参数或实参列表更容易。
操作方法
- 将光标放在参数列表。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 从以下选项中选择
选择 包装每个参数 -> 对齐包装参数

选择 包装每个参数 -> 缩进所有参数

选择 包装每个参数 -> 缩进包装参数

包装二进制表达式
作用:允许您包装二进制表达式。
时机:您有一个二进制表达式。
原因:根据用户偏好,包装二进制表达式更容易阅读。
操作方法
- 将光标放在二进制表达式中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发 快速操作和重构 菜单。
- 选择 包装表达式 以接受重构。
