错误报告
本文关键字:报告 错误 | 更新日期: 2023-09-27 17:58:06
我有一个遵循命令模式的类。它有两个方法,分别是Execute和CanExecute,CanExecute检查是否调用Execute(它们源自ICommand)。CanExecute调用一些方法来检查所有必需的服务是否正在运行、版本是否正确等。
调用CanExecute后,它可能会失败并返回false,我需要知道原因。是因为版本不好、服务、文件丢失等原因吗?
了解问题的最佳策略是什么
一种选择是,每当所需条件失败时,我可以抛出一个异常,在消息字段中描述错误。然而,它失败的可能性是意料之中的,您不应该对常规的控制流使用异常。所以我真的不确定。
谢谢。
您可以使用一组"原因",告诉类的用户为什么CanExecute
返回false。原因可以是一个简单的CCD_ 2。
public bool CanExecute() {
var messages = new List<string>();
if (!Condition1) {
messages.Add("Missing Condition1");
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<string> Messages { get; private set; }
然后,客户端代码可以向最终用户显示消息的集合。
更新:
您还可以将新的命令与消息关联起来,为用户提供解决所发现问题的方法。在这种情况下,您可以创建自己的类来封装该信息,而不是IEnumerable<string>
:
public class Message {
public string Text { get; set; }
public ICommand Command { get; set; }
}
...
public bool CanExecute() {
var messages = new List<Message>();
if (!Condition1) {
messages.Add(
new Message {
Text = "Missing Condition1",
Command = new FixCondition1Command()
}
);
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<Message> Messages { get; private set; }
更新:根据反馈返工
由于UI需要CanExecute()返回false的原因,所以会想到两件事:
选项1:将可枚举消息属性添加到命令接口,并在调用CanExecute()期间根据需要填充它。然后,UI可以根据需要询问该属性。如果采用这种方法,请确保每次调用CanExecute()时都清除属性的内容,这样就不会丢失对状态的跟踪。
public interface ICommand
{
IEnumerable<string> Messages { get; }
bool CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public IEnumerable<string> Messages { get; private set; }
public bool CanExecute()
{
var messages = new List<string>();
var canExecute = true;
if (SomeCondition)
{
canExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
canExecute = false;
messages.Add("Another reason");
}
Messages = messages;
return canExecute;
}
public void Execute() { }
}
选项2:让CanExecute()返回一个包含bool和可枚举消息属性的对象。这使得消息显然只适用于CanExecute()的调用。然而,根据您在哪里/如何实现(例如,数据绑定),这可能会使其他场景比您想要的更复杂。
public class CanExecuteResult
{
public bool CanExecute { get; set; }
public IEnumerable<string> Messages { get; set; }
}
public interface ICommand
{
CanExecuteResult CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public CanExecuteResult CanExecute()
{
var result = new CanExecuteResult { CanExecute = true };
var messages = new List<string>();
if (SomeCondition)
{
result.CanExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
result.CanExecute = false;
messages.Add("Another reason");
}
result.Messages = messages;
return result;
}
public void Execute() { }
}
显然,具体如何处理接口、可枚举类型等取决于您自己。代码只是这个想法的一个表示。
Bool CanExecute()
{
if(!CheckXXX)
throw new Exception("CheckXXX function throws an exception")
if(!CheckYYY)
throw new Exception("CheckYYY function throws an exception")
if(!CheckZZZ)
throw new Exception("CheckZZZ function throws an exception")
return true; //everything is working fine
}