简体   繁体   中英

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. 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?
  • 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"?
  • 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)

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. It's a way to show the caller that the input could be invalid and that he/she can handle the false -case accordingly. 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

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.

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. That's why i sometimes provide a different way if i parse primitive types: 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?

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).

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"?

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)

Sounds like a reasonable use-case for a TryGet but don't provide both. 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.

So depending on your specific scenario, how likely is it, that your class is being asked for something it can't provide? 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?

Depending on the answer to the above questions in each individual case I decide which route to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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