为了账号安全,请及时绑定邮箱和手机立即绑定

我应该什么时候处理异常,什么时候应该抛出它们?

我应该什么时候处理异常,什么时候应该抛出它们?

C#
慕标5832272 2022-01-09 17:05:23
在编程时,我发现自己很难思考我的程序应该如何工作,什么时候可能会抛出异常。举个例子:    public void AddComponent(IEntityComponent component)    {        if (component == null)        {            // Should I throw an ArgumentNullException or should I just return?        }        if (ContainsComponentOfType(component.GetType()))        {            // Should I return here? Or should I throw an ArgumentException?        }        // Finally, we know we can add the component to the entity        components.Add(component);    }    public bool ContainsComponentOfType(Type componentType)    {        if (componentType == null)        {            // Should I throw an exception here? Should I return false?        }        return components.Any(c => c.GetType() == componentType);    }请注意,使用我的引擎创建游戏的人将使用上面的代码。
查看完整描述

3 回答

?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

该策略可以改变从零容忍(在那里他们可以抛出的任何点抛出异常),以宽松(我们原谅呼叫者只要我们能做到)。通常的做法是DoAction(AddComponent在您的情况下)严格并且TryDoAction(TryAddComponent)宽容。


零容忍版本:


// Strict: we are quite sure in the arguments; 

// that's why it's an exceptional case (error in the code!) if arguments are invalid

// and we fail to add 

public void AddComponent(IEntityComponent component) {

  // Contract: here we validate the input arguments

  // Since we sure in them we apply zero tolerance policy:

  // if contract is't met throw corresponding exception


  // we want not null component  

  if (component == null)

    throw new ArgumentException(nameof(component));


  // which contains at least one item of the required type

  if (ContainsComponentOfType(component.GetType()))

    throw new ArgumentException("Component must contain...",  nameof(component)); 


  // Finally, we know we can add the component to the entity

  components.Add(component);

}

宽松的实施


// Lenient: we have arguments from the (unknown) source in which we are not sure

// we want just to try adding (and get true / false) if we succeed or not

public bool TryAddComponent(IEntityComponent component) {

  // Contract: we validate the input arguments from unknown source

  // if validation fails we should not throw any exception (it's not an

  // exceptional case to get incorrect data from unreliable source) but

  // let the caller know that we don't succeed


  // We can't add if component is null

  if (component == null)

    return false;


  // We have nothing to add if component doesn't contain required items 

  if (ContainsComponentOfType(component.GetType()))

    return false;


  // Finally, we know we can add the component to the entity

  components.Add(component);


  return true;

}


// Do we really want to expose it?

// ContainsComponentOfType is an implementation detail which we keep private

private bool ContainsComponentOfType(Type componentType) {

  // Since it's a private method we can omit the check

  return components.Any(c => c.GetType() == componentType);

}

用法:由于您正在构建引擎,因此两种情况(严格和宽松)都可能出现


MyClass loader = new MyClass();


...


// Cloud Database must not be corrupted; if it is, we want to know it immediatly

loader.AddComponent(componentFromCloud);


...


// Local file can contain any data: it can be corrupted, user can try cheating etc.

if (!loader.TryAddComponent(componentFromLocalFile)) {

  // Let user know that saved data failed to be loaded 

}


查看完整回答
反对 回复 2022-01-09
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

这取决于您开发的内容以及应该如何使用它以及使用它的人...

在您开发游戏引擎的情况下,最佳实践是抛出异常并将主题转发给最终用户(使用您的引擎开发游戏的开发人员),让开发人员处理异常并做他/她想要的适当工作。

始终尝试检查所有可能的异常并提供有关异常的有用信息以及修复引发异常的错误的方法。一般异常处理是针对您对主题一无所知的未知和不需要的异常。


查看完整回答
反对 回复 2022-01-09
?
慕侠2389804

TA贡献1719条经验 获得超6个赞

这取决于对您来说错误是什么以及异常是什么,仅仅因为您的代码检测到某些事情不是它应该的那样并且它无法继续,您应该抛出一个异常。

顾名思义,异常发生在您的代码无法控制或无法控制的异常情况发生时(即网络连接中断、由于其他程序锁定文件而无法保存文件、您未控制的空引用等)。 )。

对于计算机来说,抛出异常往往代价高昂,因为它必须包含一个堆栈,其中包含发生的事情、位置以及调用堆栈状态的信息,正因为如此,您希望尽可能避免异常。

由于预计您的代码可能无法在您考虑的一组受控条件下从头到尾运行,因此控制流和返回值是一种很好的做法,这些值表明进程尚未按原样运行预计会发生,但在这种情况下,由于您控制的一些预期错误已经发生并立即通知该错误。

总结:

  • 避免为方法的流控制抛出异常,因为它们代价高昂并且会导致消耗您的程序的系统不必要的缓慢。

  • 只抛出您的代码中没有涵盖的或您无法控制的异常(即,用户正在运行的另一个程序抓取了您要使用的文件,而您没有考虑这种可能性)。

  • 尽可能多地控制您认为必要的错误,并告知用户所发生的事情的合理信息,以便他能够自己解决问题(如果他有能力),以便他可以继续使用和使用您的应用程序。


查看完整回答
反对 回复 2022-01-09
  • 3 回答
  • 0 关注
  • 172 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信