这个“模式”有名字吗?

我想知道这个“模式”是否有一个名称,其中方法签名称为TrySomething,例如int.TryParsedecimal.TryParse等。

我的同事经常使用这个命名约定 – 而不是返回值或抛出exception,他们将调用方法TryDoSomething ,如果在处理期间捕获exception,则通过out param返回。

编辑:我理解私有的例子不是TryParse方法的工作原理。 这就是发布这个…我不知道该怎么称呼它。 我同意它似乎更像是命名约定而不是模式。 感谢所有的投入。

编辑: 有趣 ……

考虑可能在常见场景中抛出exception的成员的TryParse模式,以避免与exception相关的性能问题。

要实现TryParse模式,您需要提供两种不同的方法来执行可在常见方案中引发exception的操作。 第一个方法X执行操作并在适当时抛出exception。 第二种方法TryX不会抛出exception,而是返回一个表示成功或失败的布尔值。 使用out(Visual Basic中的ByRef)参数返回成功调用TryX返回的任何数据。 Parse和TryParse方法就是这种模式的例子。

我可能会称之为错误隐藏模式 。 当您拥有通常会产生exception的代码时,您可以从创建TryX受益,而exception则会使用布尔值提前删除。 如果你看一下框架提供的方法,你会注意到TryX变种存在,只要它是非常重要的或容易出错(或者经常应该在框架中完成)来编写你自己的IsValidX方法。

如果你必须捕获exception,那么在方法中包含它是没有意义的。 您所做的只是使调试输入问题变得更加困难。 用户可能只看到失败方法的副作用 ,而不是跟踪一个好的堆栈跟踪来追踪输入失败。 更糟糕的是,在调试手头的问题时,开发人员可能必须重新创建钝程序状态才能实现故障模式。

基本上,如果先验知道操作将因exception而失败,那么提供伴随的TryX操作是合乎逻辑的。 这就是所谓的Tester-Doer模式。 操作的事后分析不是Tester-Doer ,而只是简单的exception处理

在这篇关于TryParse的post中,他们称之为Tester-Doer模式。

首先,如果你的描述是准确的,那不是int.TryParse及其兄弟姐妹的工作方式。

我承认,在我看来,这些方法稍有破坏,因为它们没有向调用者传达解析失败的原因,只是失败了。 在这方面,我希望看到一个更好的方法来处理这个问题。

事实上,在我看来,更好的方式是我在第三方库中看到的一些我不记得的东西,但基本上他们有各种自定义类型,它们有这样的Parse / TryParse方法,他们做了以下:

  1. 定义一个通用结构,它包含通过解析字符串获得的值以及传递解析结果的枚举类型的值
  2. 所有TryParse方法都返回了这个结构,并且没有out参数
  3. Parse方法简单地称为TryParse方法,然后将该枚举的各种非成功结果转换为适当的exception

同样,在我看来,这里的主要问题是它不可扩展。 如果我想使用他们的系统和类型,并添加我自己的原因,我不能这样做,但是一些变体可以很容易地解决这个问题。

在任何情况下,int.TryParse方法都不会在内部抛出任何exception。 相反,他们会经历实际解析字符串的动作,如果他们遇到他们无法应付的事情,他们只会返回虚假,就是这样,没有例外。

exception处理比没有exception的替代方案略贵,这就是为什么一些这样的核心方法针对性能进行了优化的原因。

这就是为什么在我的评论中我调用了你的模式,如果准确,愚蠢,因为你将exception处理与out参数结合起来。 一旦你检索到它,你会怎么做? 丢它? 然后你又回到了第一个方向。

我会认真看看你的模式并尝试改变它。

当然,所有这一切都取决于您对它的描述是否准确的假设。

我称之为“希望我有Option ”模式(类似于“希望我有Either ”模式 – 想象一下E:例外)。

TryXYZ(在上面的例子中)使用布尔结果和out参数模拟Option。 (对于值类型,在这种情况下它可以是Nullable – 我怀疑它对于int.TryParse和朋友来说不是这样的,因为Nullable的后来很晚才到.NET)。 通过更接近地返回exception类似于Either。

在C#中,我不建议捕获exception,只是为了将它们传递给参数一般(虽然这个“规则”可能与支持有区别的联合和模式匹配的语言不同) – 我尝试1)处理它“正确的“,但是这是定义的,在特定的情况下可能 out ; 或者2)让它去,这样打电话者可以尝试相同的。

(正如其他人所指出的,这更像是一种惯例)。

快乐的编码。

你可以称之为ExceptionSafeBridge 。 它引导您从exception世界到错误代码世界。 但我不认为这是官方的。

当您需要在例如C代码和托管代码之间架起桥梁时,这种模式常见。

设计模式通常指的是与语言无关的一般概念,所以不,这不是一种模式。 它可能是一个成语,但很可能它只是一个命名惯例,正如Aaron在评论中正确提到的那样。

是的。 它被称为Tester-Doer模式。

如果在tryparse期间出现问题,即

  int val; if(int.TryParse("2", out val)) { //do work with val } 

然后你不会通过out param捕获exception,值0表示输出,false返回为布尔值。

最好的选择是使用“是”或“作为”。

我不会真的称之为你描述模式的方法……只是一种编码实践(不是最好的)。

例如:

 private void SetObj(object obj) { int thisInt = obj as int; if(thisInt != null) { //do work } else { //handle issue } } 

以上在运行时比try / catch更有效。

如果您在不可用时使用“is”(“as”不适用于所有类型),请确保不要通过实现添加冗余,因为WITH只是使用其中一个。