首先我要说的是,我并不提倡这种做法,但我最近才看到它,我想知道是否有一个名字,我可以用它指出有罪的一方.所以这里.
现在你有了一个方法,并且想要返回一个值.你也想返回错误代码.当然,异常是一个更好的选择,但无论出于何种原因,你想要一个错误代码.记住,我在这里扮演魔鬼的拥护者.所以你创建了一个泛型类,如下所示:
class FunctionResult{ public T payload; public int result; }
然后声明你的函数:
FunctionResultMyFunction() { FunctionResult result; //... return result; }
此模式的一个变体是使用枚举来表示错误代码而不是字符串.现在,回到我的问题:这是否有一个名称,如果是这样,它是什么?
我同意这不是一个特定的反模式.根据使用情况,它可能是一种气味.有理由为什么人们实际上不想使用异常(例如,对于初学者而言,返回的错误不是'例外').
在某些情况下,您希望服务返回其结果的通用模型,包括错误和良好值.这可能由低级服务交互包装,将结果转换为异常或其他错误结构,但在服务级别,它允许服务返回结果和状态代码,而无需定义可能的异常结构.必须跨越远程边界进行翻译.
此代码也可能不一定是错误:考虑HTTP响应,其包含许多不同的数据,包括状态代码以及响应的主体.
用异常替换错误代码
嗯,这不是反模式.C++标准库利用了这一特性,.NET甚至FunctionResult
在.NET框架中提供了一个特殊的类.它被称为Nullable
.是的,这不仅限于功能结果,但它可以用于这种情况,在这里实际上非常有用.如果.NET 1.0已经有了Nullable
类,它肯定会被用于NumberType.TryParse
方法而不是out
参数.
我通常将有效负载作为(非const)引用传递,并将错误代码作为返回值传递.
我是游戏开发者,我们消除异常
Konrad是对的,C#一直使用双返回值.但我有点像C#中的TryParse,Dictionary.TryGetValue等方法.
int value; if (int.TryParse("123", out value)) { // use value }
代替
int? value = int.TryParse("123"); if (value != null) { // use value }
...主要是因为Nullable模式不能扩展到非Value返回类型(即类实例).这不适用于Dictionary.TryGetValue().并且TryGetValue比KeyNotFoundException更好(在调试器中没有"第一次机会异常",可以说更有效),比Java的get()返回null更好(如果需要空值,那么),并且比必须更高效首先调用ContainsKey().
但是,这是仍然有点扭曲-因为这看起来像C#,那么就应该使用out参数.实例化课程可能会损失所有效率提升.
(可能是Java,除了"string"类型是小写的.在Java当然你必须使用一个类来模拟双返回值.)