异常处理 - 这是一种好的做法吗?

时间:2015-06-25 12:15:33

标签: c# .net exception exception-handling

我想知道我要做的是好事还是坏事。我有那个班:

public class Element : IElement
{
    public float? Max { get; private set; }

    public float? Min { get; private set; }

    public float? Average { get; private set; }

    public bool HasValue { get; private set; }


    public void SetRange(float? min, float? max)
    {
        if (min >= max)
        {
           throw new WrongElementValueException("Min must be greater than max!");
        }
        else if (min < 0f || max < 0f)
        {
           throw new WrongElementValueException("Min/max must be greater than 0!");
        }
        else if (min > 100f || max > 100f)
        {
           throw new WrongElementValueException("Min/max must be lesser than 0!");
        }
        else
        {
            Min = min;
            Max = max;
            Average = (min + max)/2f;
            HasValue = true;
        }
    }
}

用户将使用SetRange()方法设置值。但他有一些约束,比如Min必须大于Max,并且它们都不应该大于100或小于0.

我应该在这个地方使用这些例外吗?或者有更好的方法来处理错误的用户输入? 我希望我的问题不是一般的。

4 个答案:

答案 0 :(得分:9)

这是一种恰当的做法,是的。

虽然我认为消费代码会期望ArgumentException而不是此异常类型,但这可能是一个相对较小的一点。

当输入无效且对象无法以其他方式有意义地继续时,则抛出异常是适当且预期的响应。它可以使用代码来正确使用对象,处理错误,向用户报告等等。

替代方案是让这个对象“试图弄清楚要做什么”#34;这通常会导致一些非常糟糕的编码习惯。例如......

  • 假设您想要返回错误消息而不是抛出异常。如果消费代码没有检查该错误消息怎么办?该对象将处于未知和无效状态,可能会悄悄地引入错误。如果消费代码没有检查异常,那么程序将明显地显然失败并且需要进行适当的纠正。明显和明显的失败很多比微妙和未被注意的更容易支持。
  • 假设您想要向用户显示消息&#34;代替。这需要将此对象紧密耦合到表示层,这会破坏面向对象的原则并使代码非常严格且难以维护。

这个对象做了一件事,只做了一件事。如果以不能做到这一点的方式调用它,则异常是预期的和适当的失败条件。

答案 1 :(得分:2)

只要无法使用有效的程序流(例如,连接到数据库丢失),摘要就很有用。如果值无效,则证明用户输入和抛出异常是绝对正确的,而您也可以使用已经建议的ArgumentException

答案 2 :(得分:2)

else if (min < 0f || max < 0f)
  throw new WrongElementValueException("Min/max must be greater than 0!");
else if (min > 100f || max > 100f)
  throw new WrongElementValueException("Min/max must be lesser than 0!");

我注意到已经为这种情况定义了ArgumentOutOfRangeException

if (min >= max)
  throw new WrongElementValueException("Min must be greater than max!");

这绝对应该是ArgumentException,但如果WrongElementValueException继承自ArgumentException,那就没关系。

您的一般方法是合理的。我会考虑更进一步:

HasValue = true;

为什么允许班级没有价值。考虑一下你是否添加:

public Element(float min, float max)
{
  SetRange(min, max);
}

现在你可以永远不会有一个没有设置其值的实例,并且可以完全摆脱HasValue

请注意,我已将其从float?更改为float。你可能会被建议在整个课堂上这样做。否则,如果您需要MinMax为空的情况(因此不想摆脱HasValue),则需要在{{1}中捕获该情况}}:

SetRange

(除非你有充分的理由,否则我通常也会支持public void SetRange(float? min, float? max) { if (min < 0f || max < 0f || min > 100f || max > 100f) throw new ArgumentOutOfRangeException(); if (min >= max) throw new WrongElementValueException("Min must be greater than max!"); Min = min; Max = max; if(min.HasValue && max.HasValue) { Average = (min + max)/2f; HasValue = true; } else { Average = null; HasValue = false; } } double超过double?float

顺便提一下,我们通常使用“异常处理”来讨论使用此代码的代码如何处理代码抛出异常的事实,而最好的事情取决于代码的上下文而不是这段代码。

答案 3 :(得分:-3)

如果您正确地投掷并捕获它,最好在程序中处理异常。但是在这里它是微不足道的事情,不需要抛出和对象,因为你可以通过简单的控制台打印来限制它。

在这种情况下,两者都会起作用。

当有许多内部函数调用并且您不知道哪一个会在那时导致异常时,抛出异常将非常有用。

顺便说一下你不认为这些是错误的。

if(min&gt; = max)     抛出新的WrongElementValueException(“Min必须大于max!”); //你的打印min应该大于max并且你正在检查相同的内容。