С# ICommand/RelayCommand

Недавно я начал изучать WPF (с шаблоном MVVM). У меня есть вопрос о реализации ICommand...

private ICommand _confirmOptionCommand;

public ICommand ConfirmOptionCommand
{
   get
   {
      if (_confirmOptionCommand == null)
      {
        _confirmOptionCommand = new RelayCommand(ConfirmOptionMethod);
      }
      return _confirmOptionCommand;
   }
}

private void ConfirmOptionMethod() { ... }

Но я могу написать так:

private RelayCommand _confirmOptionCommand;

public RelayCommand ConfirmOptionCommand { ... }

private void ConfirmOptionMethod() { ... }

Какие преимущества есть у ICommand? Или в чем между ними разница?


person xitryuga    schedule 01.05.2016    source источник
comment
ICommand это интерфейс, который RelayCommand реализует   -  person Ehsan Sajjad    schedule 01.05.2016


Ответы (2)


RelayCommand is и ICommand, просто другая реализация, которая позволяет вызывать делегата при выполнении команды.

Когда вы пишете ICommand вместо RelayCommand в качестве типа переменной, вам все равно нужно указывать на объект ICommand. Но у вас есть доступ только к интерфейсу ICommand. Если вам нужны другие аспекты объекта, вам нужна ссылка на производный класс. В нашем случае это ссылка RelayCommand..

Вот как может выглядеть RelayCommand (не буду компилировать, но вы поняли):

public class RelayCommand<T> : ICommand {
    private Action<T> action;

    public RelayCommand(T action){
        this.action = action;
    }

    public bool CanExecute(obj param){
        return true;
    }

    public void Execute(obj param){
        this.action((T)param);
    }

    public CanExecuteEventHandler CanExecuteChanged;

}

Существуют и другие типы ICommand, такие как RoutedUICommand, которые работают с обработчиками событий.

person wingerse    schedule 01.05.2016
comment
Хорошо, большое спасибо. Я так и думал, а теперь вы развеяли сомнения :) - person xitryuga; 01.05.2016
comment
@xitryuga, пожалуйста, примите ответ, если он ответил на ваш вопрос :) - person wingerse; 01.05.2016

Простейшим ответом на ваш вопрос было бы сделать его слабо связанным.

При этом слабосвязанный класс (ICommand) можно использовать и тестировать независимо от других конкретных классов (RelayCommand).

Подумайте, хотите ли вы изменить RelayCommand на какую-либо другую команду делегирования в будущем (например, DelegateCommand) для вызова, в этом случае потребуется больше времени и усилий, чтобы заменить всех потребителей, если вы использовали ссылку на конкретный класс (RelayCommand).

При использовании ICommand на клиенте во время потребления можно переключиться на любой конкретный класс, реализующий ICommand, без каких-либо изменений в клиенте (потребителях).

person Gopichandar    schedule 02.05.2016