2

我经常使用该模式

bool TryGetX(out X x)

当我需要从可能失败的服务中获取数据时。当客户端和服务在尝试检索数据之前都不知道数据是否可用时,我会使用它。我从来没有对以这种方式使用out参数感到完全满意,而且我从其他 SO 问题中看到它被认为是一种糟糕的模式。

但是,我还没有看到一个令人信服的替代 API,它可以向客户端提示他们的方法调用实际上可能不会返回数据。

我考虑过的替代方案:

  • X GetX(),如果服务无法提供请求的数据,则GetX()将返回null 。我不喜欢这样做,因为很多人不清楚他们需要检查是否返回null。考虑到我在处理过的遗留代码中遇到的空引用异常的数量,人们经常忽略空检查,并且用户会看到一个丑陋的异常框。至少TryGetX方法对客户端来说是清楚的,数据可能不会被返回。即使他们确实检查了 null,是否在任何地方都需要if (x == null)真的比TryGetX(out X x)更好?

  • Try/Catch,如果无法返回数据, GetX()会抛出异常。同样,客户可能没有意识到GetX()会引发异常,即使他们这样做了,您也会在代码周围散布 Try/Catches。

  • GetXResult GetX(),其中GetXResult类有两个属性:bool SuccessX x。这可能是我首选的替代方案,但是我有很多结果类在四处飘荡,使我的项目变得混乱。

返回数据但可能无法返回请求的数据的方法的最佳方法是什么?

4

1 回答 1

4

最佳方法取决于问题,我怀疑是否有适合所有问题的“最佳”方法。

X GetX(),如果服务无法提供请求的数据,则 GetX() 将返回 null。

如果服务需要返回的所有类型都是 Nullable 并且可以与所有这些类型的方法保持一致,那么这根本不是一个坏方法。为了澄清返回给客户的“null”,您可以在方法名称中包含“Try”(文档也可以帮助客户)。

Try/Catch,如果无法返回数据,GetX() 会抛出异常。

抛出或不抛出异常是应该在服务架构中做出的决定。如果您选择为所有需要的方法在该级别抛出异常,则此方法也可以正常工作。(使用文档通知客户)。

GetXResult GetX(),其中 GetXResult 类有两个属性:bool Success 和 X x。

为了解决“太多类”的问题,只需使用泛型:

sealed class Result<T> {
    private bool success = false;
    private T value;
    private Result() {
    }
    public Result(T value) {
       this.success = true;
       this.value = value;
    }
    public static Result<T> Failure() { 
       return new Result<T>();
    } 
    public bool Success {
       get {
          return this.success;
       }
    }
    public T Value {
       get {
          if (!this.success) {
             throw new InvalidOperationException();
          }
          return this.value;

       }
    }
}
于 2016-01-15T17:40:02.307 回答