我对有关例外的最佳做法有疑问。本周末,我正在研究我的小游戏,我发现自己想知道是否最好使用IF或TRY来验证NULL ...以下是同一功能的两个变体:
这是我使用IF的代码
//Using IF
void ParseGamePad() {
GamePadData pad = GamePad.GetDate(0);
foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
if(myArray.ContainsKey(btn))
if(myArray[btn]!=null)
myArray[btn](); //Execute function reference in array
}
return;
}
以下是使用Try{}Catch
//Using TRY
void ParseGamePad() {
GamePadData pad = GamePad.GetDate(0);
foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
try {
myArray[btn](); //Execute function reference in array
} catch(System.Exception e) {
// Nothing to do here
}
}
return;
}
我的方法是,当数组中不存在该元素时,IF
块比TRY
块更快,而当元素存在时,TRY
更快,但在捕获异常时速度较慢。
你们会做什么?
PS:这个项目是在嵌入式系统上,因此CPU和RAM是一个因素。
答案 0 :(得分:5)
不要对程序流使用异常 - 它们用于捕获异常情况。如果myArray[btn]
永远不应该为空,那么当它 时抛出异常会没问题,但抓住它以查看它是否为空并不是最佳做法(另外,捕获Exception
将涵盖很多的可能条件,而不仅仅是当值为null
或未找到时。
就性能而言,检查一个对象的null应该非常便宜,所以我不希望在正常情况下有任何明显的性能差异。
使用TryGetValue
可以将索引查找的数量减少两个(可以显着提升性能):
foreach(var btn in Enum.GetValues(GamePad.BUTTONS)) {
Action<Button> func; // Guessing on the type here
bool found = myArray.TryGetValue(btn, out func);
if(found && func != null)
func(); //Execute function reference in array
}
答案 1 :(得分:2)
您不应该依赖Exceptions
作为系统的正确流程,因为它们会产生性能影响。由于null检查是一个chearp异常,可能会传播调用链(可能需要一段时间,具体取决于您的堆栈深度),您应该使用无效检查。
我还要说Exceptions
应该保留意外行为。您可能会认为持有空值的Dictionary
是您程序中的异常行为,这很好,因为它是基于意见的。我肯定会反对它。
您应该继续检查How expensive are exceptions in C#?,了解有关异常和效果的出色链接。
答案 2 :(得分:2)
如果我怀疑myArray是一个词典,你可以使用TryGetValue。
在这种情况下捕获异常不是一个好的解决方案。
第一个选项有一个(非常)轻微的问题,因为你要两次查找该项目,所以我会使用TryGetValue。 (如果myArray是一个词典,那么myArray就不是一个好名字。)
答案 3 :(得分:1)
至少,我不会抓住Exception
,而是更特殊的异常类型。