何时“尝试”方法优于“空”结果?

时间:2012-02-07 20:14:28

标签: .net design-patterns

在.NET Framework中(围绕泛型的出现),出现了Try[method]模式,以帮助处理一个操作需要指示它无法成功完成而不抛出异常的情况。

在失败被认为是正常的情况下(例如解析)而非例外情况,这显然是一种理想的模式。

但是,如果方法可以返回null以指示它未能成功获取值(例如在Find方法的情况下),那么这被认为比{{1}更正确使用返回值清楚地表明成功或失败的方法? .NET Framework是否为此模式设置了先例?

7 个答案:

答案 0 :(得分:2)

null返回类型的问题是您需要检查它 - 这可能不是很明显,很容易忘记。

使用Try*类型方法可以使流程更加清晰。

话虽如此,null object pattern完全是因为返回null的问题而存在 - 它允许你为你的类型使用一个“null”对象,一个代表中性值的有效对象。

答案 1 :(得分:2)

  1. 正常值类型不支持null。虽然存在可空值的类型,但泛型不支持以下构造:如果T?是值类型,则返回T;如果是引用类型,则返回T
  2. 在支持null的类型上,null是有效值。用户可能希望区分缺失的条目和null的条目。
  3. 另一方面,可以定义返回的Option<T>结构。这种类型在其他地方也很有用(例如可选参数)。


    有趣的是,当元素不存在时,非泛型HashTable类在其索引器中返回null

      

    与指定键关联的值。如果找不到指定的键,尝试获取它将返回null,并尝试设置它使用指定的键创建一个新元素。

         

    要区分由于未找到指定的键而返回的null和由于指定键的值为null而返回的null,请使用Contains方法或ContainsKey方法来确定列表中是否存在该键。

答案 2 :(得分:2)

我相信TryX模式早于Nullable<T>类型,这些类型是在.NET 2.0中添加的。 Nullable<T>解决了值类型的问题以及默认类型值是有效/无效之间可能存在的差异。然而,即使有这些新增功能,我也相信TryX模式仍然具有价值。

TryX模式的两个主要好处是:

  • 没有返回值的含糊不清。
  • 例外安全。

Nullable<T>类型消除了歧义,但不提供异常安全性。

我不相信有一个具体的优先级设置,但如果你的方法需要保证这些,那么我会使用TryX模式。

答案 3 :(得分:1)

相当多的TryParse方法返回值而不是对象意味着它们不能返回null。当然可以引入Nullable,它们可以被写为返回null但null被定义为“无信息”。如果异常/错误在语义上不正确。在成功时返回真实,在失败时返回假,清楚地代表了这些信息。 如下所述,这也与.NET框架中的TryParse方法的设计一致。它们与Nullable同时被引入 你也避免使用返回值而不检查null的某个人,这比错误更容易做到而忘记检查TrySomthing方法的结果

答案 4 :(得分:0)

异常永远不应该用于流量控制或方法的结果。当然,这条规则总是有例外。这是使用TryParse而不是Try

的部分原因

答案 5 :(得分:0)

一个原因是当你返回一个不能null的结构时,即。 double.TryParse()

答案 6 :(得分:0)

对于返回类类型的方法,我更喜欢TryGetFnord()方法,该方法在失败时返回null,优先于返回bool并将其结果存储在ref参数中的方法。除其他外,可以在协变界面中包括前一种风格,而后一种风格则不能这样做。但是,我建议在名称中保留“Try”,以表明该方法可能失败。

另一种需要考虑的方法是:dataType TryGetFnord(ref TryGetFnordResult result),其中TryGetFnordResult可以是值类型或不可变类类型,它指示操作是否成功。这将保留协方差相关的优势,同时允许返回比仅传递失败更有用的信息。如果操作失败,它应该返回其类型的默认值,但调用者应使用result参数检查失败。