gpt4 book ai didi

c# - 我什么时候应该处理异常以及什么时候应该抛出异常?

转载 作者:行者123 更新时间:2023-12-03 19:42:45 24 4
gpt4 key购买 nike

在编程时,我发现自己很难思考当可能抛出异常时我的程序应该如何工作。

看下面的例子:

    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);
}

请注意,使用我的引擎创建游戏的人将使用上述代码。

最佳答案

该策略可以变化,从零容忍(在任何可以抛出异常的地方抛出异常)到宽松(我们尽可能原谅调用者)。常见的做法是 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
}

关于c# - 我什么时候应该处理异常以及什么时候应该抛出异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52252042/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com