简体   繁体   English

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

[英]Exception Handling - is this good practice?

I am wondering if what i am going to do is good or bad thing. 我想知道我要做的是好事还是坏事。 I have that class: 我有那个班:

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

The user will set the values using SetRange() method. 用户将使用SetRange()方法设置值。 But he has some constraints like Min must be bigger than Max, and neither of them should be bigger than 100 or lesser than 0. 但是他有一些约束,比如Min必须大于Max,并且它们都不应该大于100或小于0。

Should I use those exceptions in this place? 我应该在这个地方使用这些例外吗? Or is there any better method to handle wrong user input? 或者有更好的方法来处理错误的用户输入? I hope my question isn't to general. 我希望我的问题不是一般性的。

This is an appropriate practice, yes. 这是一种合适的做法,是的。

Though I imagine consuming code would be expecting an ArgumentException rather than this exception type, but that may be a relatively minor point. 虽然我想消费代码会期望ArgumentException而不是这个异常类型,但这可能是一个相对较小的一点。

When the input is invalid, and the object has no way of meaningfully continuing otherwise, then throwing an exception is an appropriate and expected response. 当输入无效,并且对象无法以其他方式有意义地继续时,则抛出异常是适当且预期的响应。 It's up to consuming code to use the object properly, handle errors, report back to the user, etc. 由消耗代码来正确使用对象,处理错误,向用户报告等等。

The alternative is for this object to "try to figure out what to do" which often leads to some pretty bad coding practices. 替代方案是这个对象“试图弄清楚要做什么”,这通常会导致一些非常糟糕的编码实践。 For example... 例如...

  • Suppose you instead want to return an error message instead of throwing an exception. 假设您想要返回错误消息而不是抛出异常。 What if consuming code doesn't check for that error message? 如果使用代码不检查该错误消息怎么办? The object would be left in an unknown and invalid state and could quietly introduce bugs. 该对象将处于未知和无效状态,可能会悄悄地引入错误。 Whereas if consuming code didn't check for the exception then the program would clearly and obviously fail and would need to be appropriately corrected. 如果消费代码没有检查异常,那么程序将明显地显然失败并且需要进行适当的纠正。 Clear and obvious failures are a lot easier to support than subtle and unnoticed ones. 清除和明显的失败比微妙和被忽视的人更容易了很多支持。
  • Suppose you want to "show a message to the user" instead. 假设您想要“向用户显示消息”。 That would requiring tightly coupling this object to a presentation layer, which defeats object oriented principles and makes the code very rigid and difficult to maintain. 这需要将此对象紧密耦合到表示层,这会破坏面向对象的原则并使代码非常严格且难以维护。

This object does one thing, and only that one thing. 这个对象做了一件事,只做了一件事。 If it's invoked in such a way that it can't do that one thing, an exception is an expected and appropriate failure condition. 如果以不能做那件事的方式调用它,则异常是预期的和适当的失败条件。

An excption is usefull whenever a valid program-flow is not possible (eg connection to database lost). 只要不可能有效的程序流(例如,连接到数据库丢失),摘要就很有用。 Proofing user-input and throwing exception if values are not valid is absolutely ok thus, whereas you may also use the allready suggested ArgumentException . 如果值无效,则证明用户输入和抛出异常是绝对正确的,而您也可以使用已经建议的ArgumentException

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!");

I'd note that there is already ArgumentOutOfRangeException that's defined for precisely this sort of case. 我注意到已经存在ArgumentOutOfRangeException ,它正是为这种情况定义的。

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

This should definitely be an ArgumentException , but if WrongElementValueException inherits from ArgumentException , then that's fine. 这应该是一个ArgumentException ,但如果WrongElementValueException继承自ArgumentException ,那就没关系。

Your general approach is sound. 你的一般方法是合理的。 I'd consider going further: 我会考虑进一步:

HasValue = true;

Why allow for the class to ever not have a value. 为什么允许班级没有价值。 Consider if you add: 考虑一下你是否添加:

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

Now you can never have an instance without its values set, and can get rid of HasValue entirely. 现在你永远不会没有设置其值的实例,并且可以完全摆脱HasValue

Note though that I changed this from float? 注意虽然我从float?改变了这个float? to float . float You might well be advised to do that throughout the class. 你可能会被建议在整个课堂上这样做。 Otherwise if you have a need for cases where Min and Max are null, (and therefore don't want to get rid of HasValue ) you need to catch that case in SetRange : 否则,如果您需要MinMax为空的情况,(因此不想摆脱HasValue ),您需要在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;
    }
}

(I'd also generally favour double and double? over float and float? unless you've a strong reason otherwise). (我通常也喜欢doubledouble?超过floatfloat?除非你有充分的理由否则)。

Incidentally, we generally use "exception handling" to talk about how code that's using this code deals with the fact that your code threw an exception, with just what the best thing to do is depending on the context of that code rather than this code. 顺便提一下,我们通常使用“异常处理”来讨论使用此代码的代码如何处理代码抛出异常的事实,而最好的事情取决于代码的上下文而不是代码。

It's good practice to handle exception in program if you are throwing and catching it correctly. 如果正确地抛出并捕获它,最好在程序中处理异常。 But here it's trivial matter ,no need to throw and object where as you can restrict it by simple console print. 但是在这里它是微不足道的事情,不需要抛出和对象,因为你可以通过简单的控制台打印来限制它。

Both will work same in this scenario. 在这种情况下,两者都将起作用。

Throwing an exception would much useful when there are many inner function calls and you don't know which one will cause exception at that time. 当有许多内部函数调用并且您不知道哪一个会在那时导致异常时,抛出异常将非常有用。

and By the way don't you think these is wrong one. 顺便问一下你不觉得这些是错的。

if (min >= max) throw new WrongElementValueException("Min must be greater than max!"); if(min> = max)抛出新的WrongElementValueException(“Min必须大于max!”); // your are printing min should be greater than max and you are checking the same. //你的打印最小值应该大于最大值,你检查的是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM