这里有一个常见的重构,我认为我没有看到它的快捷方式:
假设我们有一个基类,它有许多继承的子类。基类使用构造函数注入来接受许多服务:
class FooBase
{
private IMyService _myService;
private IMyOtherService _myOtherService;
public FooBase(IMyService myService, IMyOtherService _myOtherService)
{
_myService = myService;
_myOtherService = myOtherService;
}
}
class FooConcrete : FooBase
{
public FooConcrete(IMyService myService, IMyOtherService _myOtherService)
base(myService, myOtherService)
{
}
}
注意FooConcrete如何调用其基类FooBase的构造函数。
现在,如果我想向FooBase添加另一个服务,会发生什么?我可以从FooBase的构造函数中快速初始化新的私有字段。但我仍然需要四处走动,手动更新从FooBase继承的每个子类。如果有很多继承类,这可能会很麻烦。
有没有一个快捷方式,或者我可以使用的技巧,可以快速更新所有子类的构造函数?
由于我问了这个问题,Resharper现在添加了对更改签名功能的支持。
例如,要向基类中的构造函数添加参数,请使用以下方法:
-
右键单击要更改的构造函数,选择Refactor->change Signature。
-
进行所需更改,然后单击"下一步"。选择"使用调用树解决",然后单击"下一步"。
-
您将进行更改,并且在Visual Studio中的某个位置将打开一个名为"重构-更改签名"的窗口。继承类的列表将显示在此窗口中。
-
双击每个类并选择"在构造函数y中创建参数x"
编译,然后修复编译错误。
ReSharper没有这方面的工具,包括今天推出的ReSharper 6中的AFAIK。
更改签名中的默认值
据我所知,最好的方法是通过Change Signature(Ctrl+R,S)将新的服务参数添加到FooBase
构造函数中,并将适当的参数名称作为默认值,例如yetAnotherService
。
之后,在所有子类构造函数中的base
调用中确实存在错误。但您只需按3个键就可以修复每个错误:
-通过Alt+Shift+Page Down,
返回错误-通过Alt+Enter打开上下文菜单,
-通过输入选择第一个选项(在包含构造函数中创建参数'yetAntherService')。
好吧,你还有很多关键笔划。但这是我所知道的最快的方式(ReSharper 5.1.3)。
ReSharper重构的参数类
如果你知道构造函数在整个生命周期中都会发生变化,你可以创建一个参数类,比如:
class FooInfo
{
IMyService MyService {get; set;}
IMyOtherService MyOtherService {get; set;}
}
并且可以将这样的对象传递给构造函数,即:
class FooBase
{
private FooInfo _fooInfo;
public FooBase(FooInfo fooInfo)
{
_fooInfo= fooInfo;
}
}
class FooConcrete : FooBase
{
public FooConcrete(FooInfo fooInfo)
base(fooInfo)
{
}
}
然后,如果您需要一个新的参数,只需将其添加到FooInfo
类中即可。不需要更改子类。
ReSharper有一个重构,用于从构造函数参数生成这样的参数类:
将光标放在代码文件中的构造函数名称上并
按Ctrl+Shift+R和
选择从参数中提取类。