C# bool-TryGetX(out X)模式的替代方案

C# bool-TryGetX(out X)模式的替代方案,c#,trygetvalue,C#,Trygetvalue,我经常使用这种模式 bool TryGetX(out X x) 当我需要从可能失败的服务获取数据时。当客户机和服务在尝试检索数据之前都无法知道数据是否可用时,我使用这种方法。我从来没有对这样使用out参数感到完全满意,我从其他SO问题中看到,它被认为是一个糟糕的模式 然而,我还没有看到一个令人信服的替代API,它可以向客户机提示他们的方法调用实际上可能不会返回数据 我考虑过的备选方案: X GetX,如果服务无法提供请求的数据,则GetX返回null。我不喜欢这样做,因为很多人不清楚他们是否需

我经常使用这种模式

bool TryGetX(out X x)
当我需要从可能失败的服务获取数据时。当客户机和服务在尝试检索数据之前都无法知道数据是否可用时,我使用这种方法。我从来没有对这样使用out参数感到完全满意,我从其他SO问题中看到,它被认为是一个糟糕的模式

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

我考虑过的备选方案:

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

Try/Catch,如果无法返回数据,GetX将抛出异常。同样,客户机可能没有意识到GetX会抛出异常,即使他们意识到了,代码中也会出现Try/catch

GetXResult GetX,其中GetXResult类有两个属性:bool Success和X。这可能是我更喜欢的选择,但我有很多结果类四处浮动,使我的项目变得混乱


对于返回数据但可能无法返回请求的数据的方法,最好的方法是什么?

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

X GetX,其中如果服务无法提供 请求的数据

如果服务需要返回的所有类型都是可空的,并且与所有这些类型的方法都有某种程度的一致性,那么这根本不是一种糟糕的方法。为了澄清返回给客户机的“null”值,您可以在方法名文档中包含“Try”,这也有助于客户机

Try/Catch,在这里,如果无法读取数据,GetX将抛出异常 返回

抛出或不抛出异常是应该在服务体系结构中做出的决定。如果您选择在该级别为所有需要抛出异常的方法抛出异常,那么这种方法也可以很好地工作。使用文档通知客户

GetXResult GetX,其中GetXResult类有两个属性:bool 成功与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;

       }
    }
}

创建一个Maybe类型,对可能不存在的值进行编码并返回该值。您是否考虑过只使用X TryGetX,如果尝试失败,它可能返回null?如果X可以是一个值类型,这可能不是一个好主意。@LasseV.Karlsen这与列出的第一个选项有何不同?我可能更喜欢Try/Catch模式。至少,如果用户没有意识到调用可能会失败,那么至少会从问题发生的地方抛出异常。@Hogan至少对我来说,更清楚的是,尝试可能会失败,因此不会返回对象。你能补充一下为什么使用out参数不好吗?或者你认为不是吗?@Greenbribbon我不认为在任何情况下都是不好的,OP需要另一种方法。无论如何,你可以阅读,也可以。谢谢你的链接。MSDN页面列出了中级技能。如果是这样的话,我希望任何在我的代码库工作的人都是中等技能的,或者至少在第一次遇到的时候把他们作为一种机会来建立他们的技能。@ GreenRibbon,你可以这样做,但是你应该认为技能不是唯一的问题。另一方面,它不是IMO语言的一个不可使用的特性,但为了简单和更干净的代码,我会尽可能避免使用它。