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+.) 触发快速操作和重构菜单。
- 选择生成构造函数
(<成员类型>, <成员类型>, <等等>) 。
添加 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+.) 打开快速操作和重构菜单。
- 选择使用 <您的引用> 添加缺失的引用。
添加命名参数
是什么:在函数调用中为指定的参数值附加命名参数。
何时使用:如果您的方法有很多参数,可以添加命名参数以提高代码可读性。
如何操作
- 将光标置于函数调用中的参数内。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择添加参数名称 <参数名称>。
将匿名类型转换为类
是什么:将匿名类型转换为类。
何时使用:您有一个匿名类型,想要在类中继续构建它时。
原因:如果您只在本地使用匿名类型,它们会很有用。随着代码的增长,有一种简单的方法将它们提升为类会很方便。
如何操作
- 将光标置于匿名(
var
)类型中。 - 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择转换为类。
在自动实现的属性和完整属性之间转换
是什么:在自动实现的属性和完整属性之间转换。
何时使用:属性的逻辑已更改。
原因:您可以手动在自动实现的属性和完整属性之间转换,但此功能会自动为您完成工作。
如何操作
- 将光标置于属性名称上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 从以下两个选项中选择
选择转换为完整属性。
选择使用自动实现的属性。
在直接转换和 'as' 表达式之间转换
是什么:使用 as
关键字在常规转换和尝试转换之间转换变量。
何时使用:当您预期转换在某些场景下会失败(as
)或如果从不预期转换会失败(直接转换)时。
如何操作
- 将光标置于变量上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 从以下两个选项中选择
选择更改为转换。
选择更改为 as
表达式。
在 for 循环和 foreach 语句之间转换
是什么:如果代码中有 for 循环,可以使用此重构将其转换为 foreach 语句。
原因:您可能想将 for 循环转换为 foreach 语句的原因包括
- 您不在循环内部使用局部循环变量,除非作为访问项目的索引。
- 您希望简化代码并减少初始化器、条件和迭代器部分中的逻辑错误的可能性。
您可能想将 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+.) 触发快速操作和重构菜单。
- 选择生成构造函数 <类名>()。
生成参数
是什么:自动生成方法参数。
何时使用:您在方法中引用了当前上下文中不存在的变量并收到错误时;您可以生成参数作为代码修复。
原因:您可以快速修改方法签名而不会丢失上下文。
如何操作
- 将光标置于变量名称中。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择生成参数。
显式实现所有成员
是什么:在类中显式定义接口的方法。显式接口实现是一个类成员,只能通过指定的接口调用。
何时使用:当
- 您不希望同一实现被多个接口调用时。
- 您想解决两个接口声明了同名但不同成员(例如属性和方法)的情况时。
如何操作
- 将光标置于类中正在实现的接口上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择显式实现所有成员
隐式实现所有成员
是什么:在类中隐式定义接口的方法。隐式接口实现是指接口的方法和属性直接添加到类中作为公共方法。
如何操作
- 将光标置于类中正在实现的接口上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择实现接口
内联方法
是什么:内联方法重构。
何时使用:您希望将静态、实例和扩展方法的用法替换为单个语句体,并可以选择删除原始方法声明时。
原因:此重构提供了更清晰的语法。
如何操作
- 将光标置于方法用法上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 从以下选项中选择
选择内联 <合格方法名> 以删除内联方法声明
选择内联并保留 <合格方法名> 以保留原始方法声明
内联临时变量
是什么:允许您删除临时变量并用其值替换它。
何时使用:使用临时变量使代码难以理解时。
原因:删除临时变量可以使代码更容易阅读。
如何操作
- 将光标置于要内联的临时变量名称内。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 选择内联临时变量。
为表达式引入局部变量
是什么:允许您立即生成局部变量来替换现有表达式。
何时使用:您有可以轻松重用(如果放在局部变量中)的代码时。
原因:您可以多次复制粘贴代码以在不同位置使用,但最好执行一次操作,将结果存储在局部变量中,并在整个代码中使用该局部变量。
如何操作
- 将光标置于要分配给新局部变量的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 从以下选项中选择
选择引入局部变量 -> 为 <表达式> 引入局部变量
选择引入局部变量 -> 为 <表达式> 的所有出现引入局部变量
引入参数
是什么:允许您立即生成新参数来替换现有表达式。
何时使用:您有可以轻松重用(如果放在参数中)的代码时。
原因:您可以多次复制粘贴代码以在不同位置使用,但最好执行一次操作,将结果存储在参数中,并在整个代码中使用该参数。
如何操作
- 将光标置于要分配给新参数的表达式上。
- 按 ⌘. (Windows, Linux Ctrl+.) 触发快速操作和重构菜单。
- 从以下选项中选择
选择为 <表达式> 引入参数 -> 并直接更新调用位置
选择为 <表达式> 引入参数 -> 到提取的方法中
选择为 <表达式> 引入参数 -> 到新重载中
引入 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+.) 触发快速操作和重构菜单。
- 选择“**换行表达式**”以接受重构。