Resharper为ReactiveUI的ReactiveObject创建自定义重构

时间:2013-09-30 18:24:40

标签: c# refactoring resharper reactiveui resharper-8.0

所以我的代码中有大量的视图模型和模型,要求每个属性都使用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; }
}

然后我必须手动将其转换为上面的第一个代码片段,以便合并我的ReactiveUI功能。

我想弄清楚的是,是否有办法为Resharper编写自定义重构,这将允许我在光标位于顶部时出现的工具菜单中添加“转换为反应属性”快捷方式一个简单的物业会员? (已经存在的'转换为自动财产'和'转换为具有变更通知的财产'选项已经存在。

非常感谢任何帮助!在编码时,这将为我节省大量的时间......

2 个答案:

答案 0 :(得分:10)

开箱即用,ReSharper支持ReactiveUI的ReactiveUI.raisePropertyChanged(string)重载,将自动属性转换为具有更改调用的属性,即:

转过来:

进入这个:

这是由ReSharper在ReSharper 7中引入的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,现在您就可以将自动属性转换为更改通知:

希望这有帮助!

答案 1 :(得分:2)

我自己从未尝试过,但我一直想自己写一个R#模板。根据这个post,这对你有用吗?

private $Type$ $BackingField$;
public $Type$ $Property$
{
  get
  {
    return this.$BackingField$;
  }
  set
  {
    this.RaiseAndSetIfPropertyChanged(ref $BackingField$, value); 
  }
}