为什么在公共方法上使用像bool throwException这样的参数是不好的?

时间:2015-11-12 08:27:58

标签: .net exception

我通常使用这种方法(函数)来测试条件是否有效:

Function IsShapeSelected(ByRef oShape As Object, Optional bThrowExc As Boolean = False) As Boolean
    'Detect if a shape is selected
    Dim bOk As Boolean
    'Test if shape (and return it byref) is selected (using Try Catch if necessary)
    'oShape = Cast (Selection..)
    'bOk = True/False 
    '
    If Not bOk And bThrowExc Then
        '...
        Throw New CMyProgException("No shape is selected...") 'Throw a localized error message..
    End If
    Return bOk
End Function

并像这样使用它:

Sub ExemplesOfMainMethodsUsinIt()
    Dim oShape As Object
    Try
        'Example1 :
        'If i want to display message in case shape is not selected
        If Not IsShapeSelected(oShape, True) Then Exit Sub
        '...continue process, ex rename shape,..
        'Example2 (supposed to be in another exemple procedure)
        'If i want to get the style of the shape for example
        Dim sStyle As String = If(IsShapeSelected(oShape, False), oShape.Style, "AnyDefaultStyle")
        '...continue process, ex: applystyle to all shapes..
    Catch ex As Exception
        'Display error message
    End Try

End Sub

我发现它非常方便,但我最近阅读过(MSDN或在论坛中): 在公共方法上使用bool throwException等参数并不好 - 参考" .NET Framework设计指南"书。

但没有任何解释原因......

是因为该方法部分不清楚(返回bool结果或抛出异常)并且可能被滥用或出于任何其他原因? (这似乎是一个简单的问题,但它是我的大部分方法的基本模式,我宁愿避免受孕错误......)。感谢。

更新:将方法名称从TryShapeSelected更改为IsShapeSelected - TryShapeSelected假设有一个ShapeSelected方法,因为TryXXX模式为Simon,Phil声明

2 个答案:

答案 0 :(得分:2)

为了扩展Jamiec给出的答案,除了它只是一个约定之外,一个原因是,不使用这种行为的方法通常是该方法可能因为无关的原因而抛出其他异常。所以你有一个bool throwOnError可以设置为false,但这只会关闭一些特殊异常的抛出,结果你仍然需要异常处理代码。这可能会使该方法的消费者感到困惑。

然而,或许主要原因可能是,方法应该被视为建立一个合同,规定它们如何与消费者互动;该合约的一部分是预期的有效输入范围,以及当输入超出该范围时给出的行为。如果将这样的throwOnError传递给方法,则有效地允许合同更改,而不仅仅是从消费者到消费者,但可能在运行时,这又会导致不可靠且更难以维护的代码(因为混淆)或快捷方式)。

对Jamiec在此处所说的Do / TryDo模式(在本例中为Date解析)进行了非常简短的讨论:https://msdn.microsoft.com/en-us/library/ms229009(v=vs.110).aspx

更新:我应该补充一点,我并不意味着诋毁惯例的用处和力量;惯例本身就是提供可靠系统的一种非常强大的方式,所以也许我只使用'在第一段给出了错误的印象。尽管如此,有时还有其他理由将某些做法作为惯例。

答案 1 :(得分:1)

  

为什么在公共方法上使用像bool throwException这样的参数

是不好的

仅仅因为它不是.NET应用程序设计指南的惯例。这并不意味着你不能这样做,只是意味着如果你遵循设计惯例,那么其他程序员会感谢你。当然,这可能与您的情况无关 - 但可能在将来。所以现在就习惯它。

为了完整起见,正确的方法是拥有2个版本的方法。如果它不起作用,DoSomething将抛出异常。 TryDoSomething会返回一个布尔值,而会在失败时抛出异常。

您的代码看起来像

Function TryShapeSelected(ByRef oShape As Object) As Boolean
    'Detect if a shape is selected
    Dim bOk As Boolean
    'Test if shape is selected (using Try Catch if necessary)
    'bOk = True/False     '
    Return bOk
End Function

Function ShapeSelected(ByRef oShape As Object) 
    'Detect if a shape is selected
    'Test if shape is selected (using Try Catch if necessary)    
End Function