重命名重构 (C#)
**“重命名”**是 Visual Studio 集成开发环境 (IDE) 中的一项重构功能,为重命名代码符号(如字段、局部变量、方法、命名空间、属性和类型)的标识符提供了一种简单的方法。 **“重命名”**功能可用来更改注释和字符串中的名称,还可用于更改标识符的声明和调用。
备注
在使用 Visual Studio 的“源代码管理”时,请在尝试执行重命名重构前,获取最新版本的源文件。
通过以下 Visual Studio 功能可以使用重命名重构功能:
功能 |
IDE 中的重构行为 |
---|---|
代码编辑器 |
在“代码编辑器”中,将光标置于某些类型的代码符号上时,可以使用重命名重构功能。 当光标在此位置时,可以通过键入键盘快捷方式调用 *** 重命名 *** 命令(CTRL + R,CTRL + R "),或者通过选择 *** 重命名 *** 命令从智能标记、快捷菜单或 *** 重构 *** 菜单。 |
类视图 |
在“类视图”中选择标识符时,可以从快捷菜单和“重构”菜单中使用重命名重构功能。 |
对象浏览器 |
在“对象浏览器”中选择标识符时,只能在“重构”菜单中使用重命名重构功能。 |
Windows 窗体设计器的“属性网格” |
在 Windows 窗体设计器的“属性网格”中,更改控件名称将启动该控件的重命名操作。 不会显示“重命名”对话框。 |
解决方案资源管理器 |
在“解决方案资源管理器”中,快捷菜单中提供了“重命名”命令。 如果选定的源文件包含类名与文件名相同的类,则可以使用此命令同时重命名源文件并执行重命名重构。 例如,如果创建默认的基于 Windows 的应用程序,然后将 Form1.cs 重命名为 TestForm.cs,则源文件名 Form1.cs 将更改为 TestForm.cs,并且 Form1 类以及对该类的所有引用都将重命名为 TestForm。
说明
“撤消” 命令 (Ctrl+Z) 将仅撤消代码中的重命名重构操作,而不会将文件名改回原始名称。
如果选定的源文件不包含类名与文件名相同的类,则“解决方案资源管理器”中的“重命名”命令将仅重命名源文件,而不会执行重命名重构。 |
重命名操作
执行**“重命名”**时,重构引擎将执行特定于下表中描述的每种代码符号的重命名操作。
代码符号 |
重命名操作 |
---|---|
字段 |
将字段的声明和用法更改为新名称。 |
局部变量 |
将变量的声明和用法更改为新名称。 |
方法 |
将方法的名称和对该方法的所有引用更改为新名称。
说明
在重命名扩展方法时,无论此扩展方法是用作静态方法还是用作实例方法,重命名操作都将传播到该方法位于当前范围内的所有实例。有关更多信息,请参见扩展方法(C# 编程指南)。
|
命名空间 |
将声明、所有 using 语句和完全限定名中的命名空间的名称更改为新名称。
说明
重命名命名空间时,Visual Studio 还更新“项目设计器”的“应用程序”页上的“默认命名空间”属性。此属性不能通过选择“编辑”菜单中的“撤消”进行重置。若要重置“默认命名空间”属性值,必须在“项目设计器”中修改该属性。有关更多信息,请参见“应用程序”页。
|
属性 |
将属性的声明和用法更改为新名称。 |
类型 |
将类型的所有声明和所有用法都更改为新名称,包括构造函数和析构函数。 对于部分类型,重命名操作将传播到其所有部分。 |
重命名标识符
创建名为 RenameIdentifier 的控制台应用程序,然后使用以下代码示例替换 Program。
class ProtoClassA { // Invoke on 'MethodB'. public void MethodB(int i, bool b) { } } class ProtoClassC { void D() { ProtoClassA MyClassA = new ProtoClassA(); // Invoke on 'MethodB'. MyClassA.MethodB(0, false); } }
将光标放在方法声明或方法调用中的 MethodB 上。
从**“重构”菜单中选择“重命名”。 出现“重命名”**对话框。
还可以右击光标,指向上下文菜单中的**“重构”,然后单击“重命名”以显示“重命名”**对话框。
在**“新名称”**字段中键入 MethodC。
选择**“在注释中搜索”**复选框。
单击**“确定”**。
在**“预览更改”对话框中单击“应用”**。
使用智能标记重命名标识符
创建名为 RenameIdentifier 的控制台应用程序,然后使用以下代码示例替换 Program。
class ProtoClassA { // Invoke on 'MethodB'. public void MethodB(int i, bool b) { } } class ProtoClassC { void D() { ProtoClassA MyClassA = new ProtoClassA(); // Invoke on 'MethodB'. MyClassA.MethodB(0, false); } }
在 MethodB 的声明中,键入方法标识符或在方法标识符上按 Backspace。 此标识符下将显示智能标记提示。
备注
只能在标识符声明中使用智能标记来调用重命名重构功能。
键入键盘快捷键 Shift+Alt+F10,然后按向下键以显示智能标记菜单。
- 或 -
将鼠标指针移至智能标记提示上,以显示该智能标记。 然后将鼠标指针移至该智能标记上,并单击向下键以显示智能标记菜单。
要调用不具有代码更改预览的重命名重构功能,请选择**“将‘<identifer1>’重命名为‘<identifier2>’”**菜单项。 对“<identifer1>”的所有引用都将自动更新为“<identifier2>”。
- 或 -
要调用具有代码更改预览的重命名重构功能,请选择**“带预览重命名”菜单项。 将会显示“预览更改”**对话框。
备注
重命名已实现或已重写的成员
对于实现/重写其他类型中成员的成员,或者由其他类型中的成员实现/重写的成员,“重命名”这些成员时,Visual Studio 会显示一个对话框,说明该重命名操作将导致级联更新。 如果单击“继续”,则重构引擎将递归查找并重命名相应基类型和派生类型中的所有成员,这些基类型和派生类型与要重命名的成员之间存在实现/重写关系。
下面的代码示例包含具有实现/重写关系的成员。
interface IBase
{
void Method();
}
public class Base
{
public void Method()
{ }
public virtual void Method(int i)
{ }
}
public class Derived : Base, IBase
{
public new void Method()
{ }
public override void Method(int i)
{ }
}
public class C : IBase
{
public void Method()
{ }
}
在上面的示例中,重命名 C.Method() 也将重命名 Ibase.Method(),这是因为 C.Method() 实现 Ibase.Method()。 接着,重构引擎通过递归查找发现 Ibase.Method() 是由 Derived.Method() 实现的,因此将重命名 Derived.Method()。 重构引擎不会重命名 Base.Method(),因为 Derived.Method() 并不重写 Base.Method()。 如果在**“重命名”对话框没有选中“重命名重载”**,则重构引擎将到此停止。
如果选中了**“重命名重载”**,则重构引擎将重命名 Derived.Method(int i)(因为它重载 Derived.Method())、Base.Method(int i)(因为它由 Derived.Method(int i) 重载)和 Base.Method()(因为它是 Base.Method(int i) 的重载方法)。
备注
当重命名在被引用的程序集中定义的成员时,将显示一个对话框,说明该重命名操作将导致生成错误。
重命名匿名类型的属性
重命名匿名类型中的属性时,重命名操作将传播到具有相同属性的其他匿名类型中的属性。 下面的示例阐释了此行为。
var a = new { ID = 1};
var b = new { ID = 2};
在前面的代码中,重命名 ID 会同时更改两个语句中的 ID,因为两者的基础匿名类型相同。
var companyIDs =
from c in companylist
select new { ID = c.ID, Name = c.Name};
var orderIDs =
from o in orderlist
select new { ID = o.ID, Item = o.Name};
在前面的代码中,重命名 ID 只会重命名 ID 的一个实例,因为 companyIDs 和 orderIDs 的属性不同。