3

这是一个暴露我缺乏经验的问题:我有一个方法DoSomething()如果它不能干净地完成它,它会抛出异常。如果失败了,我会多次尝试不太准确的方法DoSomethingApproximately() ,希望它能找到足够好的解决方案;如果这也失败了,我最后打电话给DoSomethingInaccurateButGuaranteedToWork()。这三个都是属于这个对象的方法。

两个问题:首先,这种(诚然丑陋的)模式是否可以接受,还是有更优雅的方式?

其次,考虑到它可能引发异常,跟踪我调用DoSomethingApproximately()多少次的最佳方法是什么?我目前在对象中保留一个变量 iNoOfAttempts,并嵌套 try 块......这太可怕了,我很惭愧。

4

4 回答 4

4

你不应该使用异常来控制你的应用程序。

在您的情况下,我会将这三个方法组合成一个方法,并让它返回成功的特定方法,可能使用枚举或类似的东西。

于 2008-09-24T12:37:21.747 回答
2

返回错误代码而不是抛出异常。

如果这些方法失败的方式确实引发了异常,请在同一个方法中捕获它们并采取适当的措施,例如增加计数器并返回错误代码。

   bool result = DoSomething();
   while (!result && tries < MAX_TRIES) {
       result = DoSomethingApproximately(); //This will increment tries
       if (tries > THRESHOLD) {
           result = DoSomethingThatAlwaysWorks();
       }
   }
于 2008-09-24T12:33:09.027 回答
2

怎么样(伪代码):

try{ return doSomething(); }
catch(ExpectedException) { ...not much here probably...}

for(i = 0 to RETRIES){
try{ return doSomethingApproximately; }
catch(ExpectedException) { ...not much here probably...}
}

doSomethingGuaranteed();

附录:

我强烈建议您不要使用特殊的返回值,因为这意味着该函数的每个用户都必须知道某些返回值是特殊的。根据函数的范围,返回可以正常处理的范围的普通部分可能是明智的,例如空集合。当然,这可能无法区分失败和“正确”答案是空集合(在此示例中)。

于 2008-09-24T12:48:33.687 回答
2

将整个函数指针放在结构路径中。为了增加趣味,我将使用队列和一些 LINQ。

Queue<Action> actions = new Queue<Action>(new Action[] {
   obj.DoSomething,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingApproximately,
   obj.DoSomethingGuaranteed
});

actions.First(a => {
   try {
      a();
      return true;
   } catch (Exception) {
      return false;
   }
});
于 2008-09-24T13:20:54.183 回答