Best Practice for Try Catch Error Handling
我试图避免在catch中返回不正确的值,但找不到比此更好的解决方案:
1 2 3 4 5 6 7 8 9 10 11 | private SecurityLevel ApiGetSecurityLevel() { try { return _BioidInstance.GetSecurityLevel(); } catch { return SecurityLevel.High; } } |
有没有更好的方法这样做,我就不会返回错误的值?我无法更改SecurityLevel枚举。
不要捕获异常。允许异常"冒泡",以强制调用方/调用方处理设置默认安全值的操作。
如果您真的想返回一个值,那么使用
1 2 3 4 5 6 7 8 | private SecurityLevel? ApiGetSecurityLevel() { try { return _BioidInstance.GetSecurityLevel(); } catch { return null; } } |
然后使用AS:
1 2 3 | if (ApiGetSecurityLevel().HasValue == false) { // use default security level } |
是否有可能是应用程序失败的情况?也就是说,如果不能确定安全级别,用户就不能继续?
如果是这样,为什么不重新抛出并让用户界面处理它(或者让它被记录下来,不管你的商店如何工作)?
如果应用程序应该能够继续,那么选择(并记录)一些默认值,并执行您正在执行的操作。
首先,只要
第二,这不是一个很好的尝试/捕获的用途。Try/Catch不应用于正常控制流,仅用于例外情况。
如果出于某种原因,getSecurityLevel()不返回SecurityLevel枚举类型:
1 2 3 4 5 6 7 8 9 10 11 12 | private SecurityLevel ApiGetSecurityLevel() { object securityLevel = _BioidInstance.GetSecurityLevel(); if (securityLevel is SecurityLevel) { return _BioidInstance.GetSecurityLevel(); } else { throw new Exception("Invalid SecurityLevel"); } } |
如果您可以更改foction的返回类型,我会将其更改为可为空的枚举,并在catch中返回空值。
1 2 3 4 5 6 7 8 9 10 11 | private SecurityLevel? ApiGetSecurityLevel() { try { return _BioidInstance.GetSecurityLevel(); } catch { return null; } } |
除了马特的回答,让例外发生有什么错?如果您的应用程序中存在状态或访问的某些无效性,那么最好直接终止它。
你可以让例外情况浮出水面。
你什么也不能还。并使您的函数看起来结果好像apigetSecurityLevel()不是什么
在这种情况下,安全性变为二进制。
举一个安全化合物的例子,在门上,要么有人能进去,要么就不能进去。如果他们不能达到安全级别,那人就不应该通过门。
如果getSecurityLevel()方法抛出异常,则会在入口处关闭某些内容。然后授予一些任意的安全级别并允许它们通过不是一个好主意。
我会完全放弃这个方法,用更接近
1 2 3 4 5 6 7 8 9 10 11 | private bool HasSecurityLevel(SecurityLevel securityLevel) { try { return _BioidInstance.GetSecurityLevel() == securityLevel; } catch { return false; } } |
然后根据需要检查每个安全级别。
这样做的合理性是在某个时刻必须进行检查,也可以使其尽可能靠近源(当第一次获得安全级别时)。
1 2 | SecurityLevel sec = _BioidInstance.GetSecurityLevel(); return (Enum.IsDefined(Typeof(SecurityLevel), sec) ? sec : SecurityLevel.High); |
如果在枚举中定义了安全级别,它将返回_bioidinstance中的安全级别,否则将返回security level.high。
如果是我,如果我知道安全级别不能是枚举中定义的以外的任何东西,那么我只需要不使用try-catch就可以了,如果涉及到它,就让它失败。这样我就知道别的地方出了问题,我可以去修理它。
如果可以向
或者,返回SecurityLevel作为可以为空的枚举。
1 2 3 4 5 6 7 8 9 10 11 | private SecurityLevel? ApiGetSecurityLevel() { try { return _BioidInstance.GetSecurityLevel(); } catch { return null; } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class BioId { public SecurityLevel SecLevel { get; set; } } private bool ApiGetSecurityLevel(BioId bioId) { try { bioIdSecLevel = bioId.GetSecurityLevel(); return true; } catch (PossibleException) { return false; } } |
然后将其与if和if一起使用,如果返回false,那么让处理代码决定其bioid的默认安全级别。
尽管我同意其他人的观点,但实际上,你只想让异常冒泡,让高层来处理它们。尽管有时有标准不允许例外冒泡,因为它们冒泡通过的每一层都会明显影响性能,但我要说的是,无论如何,你不应该有太多的层,洋葱是复杂的,就像食人魔一样。