我正在为几何建模程序编写一个插件,并且我有一个基于 Curve 对象的抽象类。仅当曲线是平面、闭合且不与自身相交时,该曲线才被视为有效。
然后,我有一系列引用该曲线的其他方法,这些方法可以执行诸如用它制作曲面或将其挤出到体积中之类的操作。如果在 BaseCurve 无效时调用这些方法,则会抛出异常。现在,如果用户使其中一条曲线无效,我的程序就会崩溃,并且我正在尝试找出让我的程序处理此无效输入的最佳方法。
这是我的类(class)的样子:
public abstract class AbsCurveBasedObject
{
public abstract Curve BaseCurve
{
get;
}
public bool BaseCurveIsValid
{
get
{
Curve c = this.BaseCurve;
...
//checks that curve is valid
...
return true/false;
}
}
public Surface GetSurface()
{
Curve c = this.BaseCurve();
...
//magic that converts c to a surface
//exception is thrown if c is invalid
...
return surface;
}
public Surface GetVolume()
{
Surface s = this.GetSurface();
...
//magic that converts s into a volume
...
return volume;
}
}
如果曲线无效或者我是否应该抛出异常,我不确定GetSurface()是否应该返回NULL。
基本曲线无效并不意外,因为我知道用户在使用我的程序时最终会创建无效曲线。据我了解,通常只有当程序到达发生意外情况并且不知道如何继续的时候才应该抛出异常?
如果曲线无效,我是否应该只从 GetSurface() 返回 NULL,然后让基于 GetSurface() 的每个方法也返回 null(如果 GetSurface() 无效)?这看起来调试起来会更困难。我知道我最终会忘记检查某处的返回值是否为 NULL,并最终得到一些 ArgumentNullException,该异常一直跟踪到 AbsCurveBasedObject.GetSurface()
那么,当用户以某种方式使基本曲线属性无效时,最好在整个跟踪过程中使用 if/else 或 try/catch block 来处理吗?
最佳答案
理想情况下,如果可以避免异常,则永远不想抛出异常。然而,这并不一定意味着返回 null 就是正确的做法!这可能是错误的做法。
这样看。您的代码可能如下所示:
Blah MakeMeABlah(Foo foo)
{
if (!IsValid(foo)) throw new InvalidArgumentException("foo");
// [make a blah from a foo]
}
你可以让调用者看起来像这样:
Foo foo = GetFooFromUser();
try
{
blah = MakeMeABlah(foo);
}
catch(...)
{
// Tell user that input foo was invalid
}
这不太好。解决您问题的方法是将 IsValid 设为公共(public)方法:
Foo foo = GetFooFromUser();
if (!IsValid(foo))
// Tell user that input foo was invalid
else
blah = MakeMeABlah(foo);
嘿,没有异常处理,代价是必须调用 IsValid 两次。如果验证很便宜,谁在乎呢?如果验证成本很高,那么您可能需要进一步重构它,以拥有一个内部版本的 MakeMeABlah,它不会在发布版本中重新进行检查。
关于c# - 在这种情况下我应该如何处理无效的用户输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1527500/