2009-10-06 101 views
2

我正在为几何建模程序编写一个插件,我有一个基于曲线对象的抽象类。如果曲线是平面的,封闭的并且不相交,则该曲线仅被认为是有效的。在这种情况下,我应该如何处理无效的用户输入?

然后我有一系列其他方法可以引用这条曲线,这些方法可以使曲面变形或将曲面挤出成一个体。如果在BaseCurve无效时调用这些方法,则会引发异常。现在,如果用户使其中一条曲线失效,我的程序就会崩溃,我试图找出让我的程序处理这个无效输入的最佳方法。

这里是我的课是什么样子:

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()的方法在GetSurface()函数返回时都返回null,我应该从GetSurface()返回NULL吗?这似乎很难调试。我知道我最终会忘记检查某个返回值是否为NULL,并最终导致一些ArgumentNullException跟踪回溯到AbsCurveBasedObject.GetSurface()

因此,如果if/else或try/catch块在整个地方跟踪处理,当用户一些如何使基础曲线属性无效?

回答

1

C#Design guidelines官方声称抛出异常并让用户界面层处理异常。

+0

在这本优秀的书“框架设计指南”第2版中有一篇非常好的讨论。它回顾了Tester-Doer模式的优点/缺点(请参阅Eric Lippert的回答 - 缺点是线程问题)和Try-Parse模式以及众多异常指南。一般不建议返回null。 – TrueWill 2009-10-07 01:37:23

2

理想情况下,如果可以避免的话,您从不想抛出异常。但是,这并不一定意味着返回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一个公共方法:

Foo foo = GetFooFromUser(); 
if (!IsValid(foo)) 
    // Tell user that input foo was invalid 
else 
    blah = MakeMeABlah(foo); 

哎,也不例外处理,在不必调用IsValid的两倍的价格。如果验证便宜,谁在乎?如果验证费用很高,那么您可能需要进一步重构此版本,以使内部版本的MakeMeABlah不会在发布版本中重新执行检查。

0

为什么要建立曲线,如果它是无效的。使用构建器模式,您可以公开构建仅有效的Curve对象的能力,并允许UI在那里处理无效状态。

这是(我认为)埃里克的建议的本质,公开一个外部的方式来验证状态,然后再构造一个无效的对象。

注意:一旦您的建筑物只有有效的曲线对象,您可以删除可怕的if-创建布尔型“bool BaseCurveIsValid”。 :)

相关问题