Я понимаю использование CanExecute()
и Execute()
, но меня интересует следующий сценарий:
public class MyViewModel : NotificationObject
{
public MyViewModel()
{
FooCommand = new DelegateCommand(DoFoo, CanDoFoo);
}
public Bar MyBar { get; set; }
public DelegateCommand FooCommand { get; private set; }
public Boolean CanDoFoo()
{
return (MyBar != null)
}
public void DoFoo()
{
MyBar.BarFunc(); //Potential for a NullReferenceException
}
}
По сути, потребительское представление может решить обратиться непосредственно к методу DoFoo (очевидно, нарушая точку интерфейса ICommand
) и вызвать исключение NullReferenceException. Это может быть немного субъективно, но я надеюсь на «стандартный» способ сделать это.
Делаем ли мы:
- Предотвратить возможное исключение NullReferenceException, выполнив сначала
if (MyBar != null)
?
- Предотвратить возможное исключение NullReferenceException, убедившись, что
CanDoFoo()
возвращает true?
- Предположим, что потребительское представление ведет себя правильно и уже проверило, что оно может вызывать метод
DoFoo()
?
В качестве примечания, основная причина, по которой я спросил это, заключается в том, что, когда я писал модульные тесты, я понял, что кто-то может сломать мою ViewModel, вызывая
Execute()
методы, не вызывая их
CanExecute()
аналогов? Очевидно, что в своих модульных тестах я проверяю, могу ли я
выполнить метод до выполнения этого, но потребляющие представления могут решить игнорировать это.
Обновление: (Сценарий 2)
В качестве дополнения к этому вопросу я также хочу добавить в сценарий, где метод DoFoo()
не нарушает с точки зрения исключений, но может логически сломаться?
public class MyViewModel : NotificationObject
{
public MyViewModel()
{
FooCommand = new DelegateCommand(DoFoo, CanDoFoo);
}
public Int32 Age { get; set; }
public DelegateCommand FooCommand { get; private set; }
public Boolean CanDoFoo()
{
return (Age >= 21)
}
public void DoFoo()
{
ProvideAlcohal(Age);
}
}
Этот второй сценарий на самом деле не прерывается (команда может нормально работать), однако он логически разбивается. Итак, мы проверяем бизнес-логику во второй раз, вызывая CanDoFoo()
или предполагаем, что потребительское представление ведет себя? (Помните, это только нарушает бизнес-логику ).
По сути, это сводится к следующему ... Принимаем ли мы меры предосторожности, чтобы гарантировать, что потребительский взгляд не стреляет себе в ногу из-за плохого поведения?