简体   繁体   English

C# 中何时使用 Try 模式的最佳实践

[英]Best practices for when to use the Try pattern in C#

After reading a bit on the topic, I am still unsure of when to provide TryGet*(someParameter, out someValue) methods.在阅读了一些关于该主题的内容后,我仍然不确定何时提供 TryGet*(someParameter, out someValue) 方法。 I understand how it can be useful when there exists a variant of the method that can throw exceptions in the case of failure, but I can't really form a general rule that I can use to help me decide when to provide either type of method.我理解当存在可以在失败的情况下抛出异常的方法的变体时它是如何有用的,但是我不能真正形成一个通用规则来帮助我决定何时提供任何一种方法.

Some questions that come to mind about this:对此想到的一些问题:

  • Why not just have the non-try method not throw exceptions?为什么不让非尝试方法不抛出异常?
  • When would throwing an exception be better than just returning null?什么时候抛出异常比只返回 null 更好?
  • If the decision comes down to having one type of method that just returns a nullable type (or some Result type), should this always be reflected in the method's name in the sense that it has to be prefixed with "Try"?如果决定归结为使用一种仅返回可空类型(或某些 Result 类型)的方法,是否应该始终反映在方法名称中,因为它必须以“Try”为前缀?
  • Is providing both types of methods always better in every case?在每种情况下都提供两种类型的方法总是更好吗?

I am specifically working with manipulating a collection, and what I have is a bunch of methods like: void GetAt(position) bool TryGetAt(position, out item)我专门处理一个集合,我有一堆方法,比如: void GetAt(position) bool TryGetAt(position, out item)

I'm not sure whether this is needed or not, but it feels like what I'm doing is wrong in some way.我不确定这是否需要,但感觉我正在做的事情在某种程度上是错误的。

The TryParse pattern is not (just) about preventing exceptions. TryParse模式不(只是)关于防止异常。 It's a way to show the caller that the input could be invalid and that he/she can handle the false -case accordingly.这是一种向调用者显示输入可能无效并且他/她可以相应地处理false情况的方法。 So you get two information from the method:所以你从方法中得到两个信息:

  1. the parsed/resolved value in case it succeeded解析/解析的值,以防它成功
  2. a bool that indicates if the value could be resolved successfully一个bool ,指示该值是否可以成功解析

Note that you can't get the second information from the value itself because whatever you return from the method in false -case it could be a valid value.请注意,您无法从值本身获取第二个信息,因为无论您在false情况下从方法返回什么,它都可能是有效值。

The only drawback of the TryParse -pattern, that is return a bool and the value as out -parameter, is, that you can't "chain" it with other method calls. TryParse模式的唯一缺点,即返回一个bool值和作为out参数的值,是您不能将它与其他方法调用“链接”。 That's why i sometimes provide a different way if i parse primitive types: return Nullable<T> :这就是为什么我有时会在解析原始类型时提供不同的方式: return Nullable<T>

public static class StringExtensions
{
    public static int? TryGetInt(this string input)
    {
        return int.TryParse(input, out int value) ? value : new int?();
    }
    // more methods like this...
}

Why not just have the non-try method not throw exceptions?为什么不让非尝试方法不抛出异常?

Because often you can't do that because the exception comes not from your code.因为通常你不能这样做,因为异常不是来自你的代码。 But as i've said, it's not about preventing exceptions but about helping the caller of the method to understand it and to handle the result.但正如我所说,这不是为了防止异常,而是为了帮助方法的调用者理解它并处理结果。

When would throwing an exception be better than just returning null?什么时候抛出异常比只返回 null 更好?

In case of an exceptional case which is not normal program flow.在不正常程序流程的异常情况下。 But instead of returning null you should return a bool (try-get with out -parameter) or a nullable type(primitive types).但不是返回null你应该返回一个bool (try-get with out -parameter)或一个可为空的类型(原始类型)。

If the decision comes down to having one type of method that just returns a nullable type (or some Result type), should this always be reflected in the method's name in the sense that it has to be prefixed with "Try"?如果决定归结为使用一种仅返回可空类型(或某些 Result 类型)的方法,是否应该始终反映在方法名称中,因为它必须以“Try”为前缀?

Yes, that would help to understand that the method also returns the information if it succeeded.是的,这将有助于理解该方法在成功时也会返回信息。

Is providing both types of methods always better in every case?在每种情况下都提供两种类型的方法总是更好吗?

No, that's just confusing people, what method should be used?!不,那只是迷惑人,应该使用什么方法?!

I am specifically working with manipulating a collection, and what I have is a bunch of methods like: void GetAt(position) bool TryGet(position, out item)我专门处理一个集合,我有一堆方法,比如: void GetAt(position) bool TryGet(position, out item)

Sounds like a reasonable use-case for a TryGet but don't provide both.听起来像是TryGet的合理用例,但不要同时提供两者。 You haven't provided enough information though.但是,您没有提供足够的信息。

For me, the Try Pattern comes into play, when it happens quite regulary, that you don't have a match and not exceptional.对我来说, Try Pattern 开始发挥作用,当它经常发生时,你没有匹配并且不是例外。

So depending on your specific scenario, how likely is it, that your class is being asked for something it can't provide?因此,根据您的具体情况,您的 class 被要求提供它无法提供的东西的可能性有多大? And even more, what can be done in such a case?更重要的是,在这种情况下能做些什么呢? Is there something easy the caller can do (eg calling some other Try -Method, fall back to something else) or is calling your method with an invalid parameter value really something exceptional and all you can do is throwing an exception to get out of the whole stack?调用者是否可以做一些简单的事情(例如调用其他一些Try -Method,回退到其他东西)或者使用无效的参数值调用您的方法确实是异常的事情,您所能做的就是抛出异常以摆脱整个堆栈?

Depending on the answer to the above questions in each individual case I decide which route to go.根据每个案例中上述问题的答案,我决定通往 go 的路线。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM