【问题标题】:Resharper Create Custom Refactor for ReactiveUI's ReactiveObjectResharper 为 ReactiveUI 的 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 编写自定义重构,这将允许我在光标位于顶部时出现的工具菜单中添加“转换为反应性属性”快捷方式一个简单的属性成员? (在已经存在的“转换为自动属性”和“转换为带有更改通知的属性”选项之上。

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

【问题讨论】:

    标签: c# refactoring resharper reactiveui resharper-8.0


    【解决方案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 中删除了该属性,并且这两个选项都从重构上下文菜单中消失了。可能对某人来说是个问题......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 2012-04-27
    • 2015-05-22
    • 2015-02-15
    • 1970-01-01
    相关资源
    最近更新 更多