MVVM C#​​6 RelayCommand auto 或 expression-bodied 属性

MVVM C#6 RelayCommand auto or expression-bodied properties

我正在将我的项目转移到 C#6 和 Visual Studio 2015,我正在考虑改进我的代码以适应 Roselyn 的最新功能。

当前代码:

public MyViewModel()
{
    MyCommand = new RelayCommand(OnExecute, CanExecute);
}

public ICommand MyCommand { get; private set; }

自动属性

public ICommand MyCommand { get; } = new RelayCommand(OnExecute, CanExecute);

表达式主体属性

public ICommand MyCommand => new RelayCommand(OnExecute, CanExecute);

自动属性无法编译,因为 OnExecuteCanExecute 方法为此需要是静态的,我需要在这些方法中访问我的视图模型中的私有成员。

表达式体实现有效,但对于 MyCommand 属性 的每次调用 \ 数据绑定都会创建一个新的 RelayCommand。这对我来说也不对。

有人知道如何将 C#6 与 RelayCommands 合并吗?

您的 Expression-bodied 属性示例看起来不错。

public ICommand MyCommand => new RelayCommand(OnExecute, CanExecute);

旧样式是

public ICommand MyCommand
{
    get { return new RelayCommand(OnExecute, CanExecute); }
}

A​​FAIK Expression-bodied 属性只是语法糖。 => 替换大括号和关键字 get{ return }

每次调用数据绑定都会创建一个新的 RelayCommand 是标准方法。

我认为这是您可以使用 C# 6 功能在这里实现的最佳效果:

public MyViewModel()
{
    MyCommand = new RelayCommand(OnExecute, CanExecute);
}

public ICommand MyCommand { get; }

与原始 C# 5 代码的唯一区别是,您现在可以删除 属性 私有 setter,这使得它真正只读。构建对象后,您将无法从代码隐藏的任何地方更改它的值。这在设计不可变对象时非常有用。

编辑: 在更多的方法上,这是可行的,但它的可读性是有争议的。优点是您不必为了查找命令实例化而导航到 ctor。

private ICommand _myCommand;
public ICommand MyCommand => _myCommand ?? (_myCommand = new RelayCommand(Execute));