C#:当不支持参数类型时,我应该抛出ArgumentException或NotSupportedException吗?

时间:2019-04-03 19:27:26

标签: c# polymorphism custom-exceptions argumentexception notsupportedexception

因此,由于“不支持参数”,我需要抛出异常。为了说明我是如何到达这里的,这是一个粗糙的情况:

  • ok的类型很多,包括Yooks和Zooks
  • Ook可以与其他Ook成为朋友,但只有正确的类型
  • 外星人可以成为Zooks的朋友,但是Zook不能成为Yooks的朋友

代码示例:

public abstract class Ook
{
    public abstract bool TryBefriendYook(Yook yook);
    public abstract bool TryBefriendZook(Zook zook);

    public bool TryBefriend(Ook o0k)
    {
        Type ookType = ook.GetType;

        if (ookType == typeof(Yook))
        {
            TryBefriendYook((Yook)ook);
            return true;
        }
        else if (ookType == typeof(Zook))
        {
            TryBefriendZook((Zook)ook);
            return true;
        }
        else return false;
    }

    public void Befriend(Ook ook)
    {
        if(!TryBefriend(ook))
            throw new Exception(
                "argument type not supported");
    }
}

public sealed class Yook : Ook
{
    public override bool TryBefriendYook(Yook yook)
    {
        return true;
    }
    public override bool TryBefriendZook(Zook zook)
    {
        return true;
    }
}

public partial sealed class Zook : Ook
{
    public override bool TryBefriendYook(Yook yook)
    {
        return false;
    }
    public override bool TryBefriendZook(Zook zook)
    {
        return true;
    }
}

因此,这种情况属于ArgumentException(该参数不适用于子类)和NotSupportedException(子类不接受该参数)两者,不是吗? / p>

那么,我应该选择哪一个-或者应该针对这种情况编写自定义例外?

2 个答案:

答案 0 :(得分:0)

根据MSDN:

  

NotSupportedException   当不支持调用的方法或尝试读取,查找或写入不支持调用的功能的流时抛出的异常。

     

ArgumentException Class 提供给方法的参数之一无效时抛出的异常

因此,根据MSDN,ArgumentException更适合您的情况 编辑:如果绝对需要更多的参数或自定义返回,则可以编写自己的自定义异常,但是如果适合您的需要,可以使用ArgumentException。

答案 1 :(得分:0)

您不应抛出任何异常。您已声明此方法:

public bool TryBefriend(Ook o0k)

它表示此方法需要一个Ook类型的参数。有人传递了该类型或其子类之一的参数,然后进行编译,那么给他们一个运行时错误并说“实际上,不是那个类型,那不是很好。我真的是说这类型和这种类型,但不是那种。”

如果有可能尝试与某人成为朋友,但结果是成功可能成功或失败,那么尝试不应抛出异常。我们不应该使用异常来管理正常的,可预测的程序流。

想起来就像想从银行提款。如果您尝试提取$ 1000,则应该收到一条消息,说明成功或失败,因为您没有$ 1000。如果您有足够的钱,它不应该返回成功,否则则抛出异常。没有足够的钱是正常的,可预测的可能性。另一方面,如果该应用程序由于丢失了数据库连接而无法继续运行而无法恢复,则抛出异常是有道理的。

因此,我只返回truefalse,然后调用者可以根据响应决定要做什么。您会看到这,这很有意义:

if(someOok.TryBefriend(someOtherOook))
{
    // friends!
}
else
{
    // not friends!
}

...而不是这个,很尴尬:

try
{
    someOok.TryBefriend(someOtherOook);
    // friends!
}
catch(NotSupportedException ex)
{
    // not friends!
}