Resharper 为 ReactiveUI 的 ReactiveObject 创建自定义重构
Posted
技术标签:
【中文标题】Resharper 为 ReactiveUI 的 ReactiveObject 创建自定义重构【英文标题】:Resharper Create Custom Refactor for ReactiveUI's ReactiveObject 【发布时间】:2013-10-06 17:23:11 【问题描述】:所以我的代码中有大量视图模型和模型,它们要求每个属性都使用 ReactiveUI 方式来观察它们的变化:
private bool _myProperty;
public Boolean MyProperty
get return _myProperty;
set this.RaiseAndSetIfChanged(ref _myProperty, value);
使用 Resharper 我可以转换:
public Boolean MyProperty get; set;
进入这个:
private bool _myProperty;
public Boolean MyProperty
get return _myProperty;
set _myProperty = value;
然后我必须手动将其转换为上面的第一个代码 sn-p 以合并我的 ReactiveUI 功能。
我想弄清楚的是,是否有一种方法可以为 Resharper 编写自定义重构,这将允许我在光标位于顶部时出现的工具菜单中添加“转换为反应性属性”快捷方式一个简单的属性成员? (在已经存在的“转换为自动属性”和“转换为带有更改通知的属性”选项之上。
非常感谢任何帮助!这将在编码时为我节省大量时间......
【问题讨论】:
【参考方案1】:我自己从未尝试过,但我一直想自己编写一个 R# 模板。根据这个post,这对你有用吗?
private $Type$ $BackingField$;
public $Type$ $Property$
get
return this.$BackingField$;
set
this.RaiseAndSetIfPropertyChanged(ref $BackingField$, value);
【讨论】:
有趣...实际上不是一条糟糕的路线。我实际上是想弄清楚如何将其添加为重构,但我不介意将其用作模板...唯一的问题是这仅适用于新代码,而不适用于需要修改的现有属性。 ..如果我没有得到任何关于将其创建为重构的回复,尽管我会将其标记为答案【参考方案2】:开箱即用,ReSharper 支持 ReactiveUI 的 ReactiveUI.raisePropertyChanged(string)
重载,以将自动属性转换为具有更改调用的属性,即:
转这个:
进入这个:
这是由 ReSharper 7 中引入的 ReSharper 的 support for INotifyPropertyChanged
完成的。它的工作方式是 ReactiveUI.raisePropertyChanged(string)
方法使用 ReSharper 的 Annotation 属性(称为 [NotifyPropertyChangedInvocator]
)进行修饰。当使用特定签名装饰方法时,实现INotifyPropertyChanged
接口的类型上的此属性将自动允许 ReSharper 将其用作“更改通知”重构。
在您的情况下,使用相对较少的代码,您可以使用相同的机制。但是,您的 RaiseAndSetIfPropertyChanged
方法需要具有特定的签名。您可以做的是,创建一个派生自 ReactiveObject
的抽象类,并在那里实现您的方法:
public abstract class ReactiveObjectBase : ReactiveObject
[NotifyPropertyChangedInvocator]
protected void RaiseAndSetIfPropertyChanged<T>(ref T obj, T value, string propertyName)
// call real raise method here
这个方法需要有这个确切的签名(方法名称可能不同),并且必须用NotifyPropertyChangedInvocator
属性修饰。
之后,只需将视图模型的基本类型更改为ReactiveObjectBase
,现在您就可以将自动属性转换为更改通知:
希望这会有所帮助!
【讨论】:
Hmmmm...这似乎很有希望,尽管我不确定我是否需要实现任何东西。通常,当您使用该快捷方式时,resharper 会将 notifyproperrtychangedinvocator 注释方法添加到类中,但对于从 ReactiveObject 扩展的类似乎没有这样做。作为说明,我的问题中有一个错字,调用的方法是“RaiseAndSetIfChanged”(可直接从 ReactiveUI 获得),所以正如我所看到的,正如你所说的那样,它支持来自 ReactiveUI 的 raisePropertyChanged 重载我认为这已经是我想要的设置了,哈哈。 是的,看看 GitHub 上的 ReactiveUI 代码,RaiseAndSetIfChanged 方法似乎只是调用 raisePropertyChanged 方法......除了它还在进行更改之前调用 raisePropertyChanging 方法(我没有不相信会影响我)...已选择答案! 我的基类中有 OnPropChanged 和 SetProperty 方法,这两个方法都归于 NotifyPropertyChangedInvocator。我从 OnPropChanged 中删除了该属性,并且这两个选项都从重构上下文菜单中消失了。可能对某人来说是个问题......以上是关于Resharper 为 ReactiveUI 的 ReactiveObject 创建自定义重构的主要内容,如果未能解决你的问题,请参考以下文章
ReactiveUI:如何实现定期刷新的ReactiveList
如何在 Avalonia.ReactiveUI 中使用 Autofac 作为 DI 容器?
我应该如何使用 Avalonia(ReactiveUI) 控制命令的可执行性?
ReactiveUI 是不是提供类似 PRISM ViewModelLocator 的服务?