在.NET Framework中(围绕泛型的出现),出现了Try[method]
模式,以帮助处理一个操作需要指示它无法成功完成而不抛出异常的情况。
在失败被认为是正常的情况下(例如解析)而非例外情况,这显然是一种理想的模式。
但是,如果方法可以返回null
以指示它未能成功获取值(例如在Find
方法的情况下),那么这被认为比{{1}更正确使用返回值清楚地表明成功或失败的方法? .NET Framework是否为此模式设置了先例?
答案 0 :(得分:2)
null
返回类型的问题是您需要检查它 - 这可能不是很明显,很容易忘记。
使用Try*
类型方法可以使流程更加清晰。
话虽如此,null object pattern完全是因为返回null的问题而存在 - 它允许你为你的类型使用一个“null”对象,一个代表中性值的有效对象。
答案 1 :(得分:2)
null
。虽然存在可空值的类型,但泛型不支持以下构造:如果T?
是值类型,则返回T
;如果是引用类型,则返回T
。null
的类型上,null
是有效值。用户可能希望区分缺失的条目和null
的条目。另一方面,可以定义返回的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
参数检查失败。