207

We were discussing with our coworkers on what it means if the method name starts with "Try".

There were the following opinions:

  • Use "Try" when the method can return a null value.
  • Use "Try" when the method will not throw an exception.

What is the official definition? What does "Try" say in the method name? Is there some official guideline about this?

ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
ms007
  • 4,661
  • 3
  • 28
  • 31
  • 90
    +1 People who put this much thought into the names of their functions are actually looking out for "the next guy". Not sure why this is getting close votes (and that's coming from a guy who's cast *a lot* of them tonight.) – Jonathon Reinhart Jun 20 '13 at 07:34
  • 7
    @JonathonReinhart, it got close votes because _"As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or specific expertise, but this question will likely solicit debate, arguments, polling, or extended discussion."_ – Pranav Hosangadi Jun 20 '13 at 12:42
  • 19
    There *is* an official statement by Microsoft that answers the question (see my answer). How is that not a fact? – Erik Schierboom Jun 20 '13 at 13:15
  • 7
    @PranavHosangadi as Erik mentioned, it is supported by facts. Also, there are plenty of very experienced C# developers here who have *specific expertise* to provide a valid answer. Hell, Eric Lippert is the chief C# language architect. I think you can call that *specific expertise*. – Jonathon Reinhart Jun 20 '13 at 23:17
  • 2
    The question is open to debate. You can't force a team to follow a particular naming convention, and everybody will have their own conventions, supported by whatever experience they have had. There is no _right answer_ to this question is all I'm saying : every answer is just as correct as the next. – Pranav Hosangadi Jun 21 '13 at 08:50
  • 4
    @ErikSchierboom That it's the MS guideline is fact. That the MS guideline is the correct guideline to use is subjective and debatable. – Servy Jun 21 '13 at 15:02
  • 2
    @Servy that the MS best practices guidelines are the correct one for a MS-specified language is not really debatable. – Falanwe Jun 26 '13 at 06:58
  • 1
    @Servy Well I think that in most cases one should definitely go with the official Microsoft recommendations. And more specifically, in this case I feel that the recommendation is actually a very sound and sensible one. – Erik Schierboom Jun 26 '13 at 07:24
  • 2
    @Falanwe Sure it is. MS has, in some instances, best practices that just don't make sense at all and that have a *lot* to be gained by discarding. That they created the language doesn't mean that all of their best practices are the best ones, just like Oracle doesn't always have the only best practices that you should use in Java. In fact, I find a significant number of MS given best practices to be at least not exactly correct. – Servy Jun 26 '13 at 13:57
  • 2
    @ErikSchierboom That the MS guideline in this specific case is appropriate to you (or even me) doesn't change the fact that it's an opinion. It's not a question of fact, and thus isn't an appropriate question on this site. – Servy Jun 26 '13 at 13:58
  • I asked a related question a while ago: http://stackoverflow.com/questions/5505391/is-there-a-name-for-this-pattern – Dave Ziegler Jul 01 '13 at 20:00

6 Answers6

172

This is known as the TryParse pattern and has been documented by Microsoft. The official Exceptions and Performance MSDN page says:

Consider the TryParse pattern for members that may throw exceptions in common scenarios to avoid performance problems related to exceptions.

Thus if you have code for which a regular use case would mean that it might throw an exception (such as parsing an int), the TryParse pattern makes sense.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Erik Schierboom
  • 16,301
  • 10
  • 64
  • 81
  • 2
    Another useful link that documents this pattern (search for TryParse) http://blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx – V Maharajh Jun 20 '13 at 07:41
  • 2
    Basically, if you have a TryParse method, you should have a Parse method that throws when TryParse would return false. Conversely, if you have a Parse method, you should consider having a TryParse method that return false when Parse would throw – 3Doubloons Jun 20 '13 at 10:23
  • 5
    +1. Just to add to this, exceptions are generally for "exceptional" circumstances. If you're doing something that could easily fail and that failure is not particularly notable, then using this pattern is more idiomatic than a try/catch – Adam Robinson Jun 20 '13 at 12:06
  • Did such a pattern really require guidelines from Microsoft? Seems fairly basic stuff. – Dave Lawrence Jun 20 '13 at 14:08
  • 21
    It _is_ basic stuff, but that doesn't mean that guidelines are not useful. Getting basic stuff right can be quite hard if you don't know the platform well enough. – Erik Schierboom Jun 20 '13 at 14:11
  • Is there any preferred pattern for including a `Try` method in a covariant interface? One couldn't have a `VariantLookup` interface include a `bool TryGetValue(object key, out TValue value)` but the interface could include `TValue TryGetValue(object key, out bool success)` [the use of `object` for the key would allow code to ask a collection of `Cat` whether it contains an `Animal`--if asked to look up Fido (an instance of `Dog`), the collection would simply indicate that it does not contain Fido]. Is the latter a good pattern, or is some other one preferred? – supercat Jun 20 '13 at 14:41
  • 1
    @daveL: It's basic, yes, but a different convention (`ParseOrNull` and `Parse`) or even the opposite convention (`Parse` and `ParseOrThrow`) would be just as basic. The benefit of guidelines from Microsoft is that it promotes consistency: when you look at a codebase you're not familiar with, you can still understand it, because it (most likely) uses the widespread conventions endorsed by the proprietors of the platform. – ruakh Jun 21 '13 at 06:20
  • Often missed when quoting from this official guidance is this bit: "When using this pattern, it is important to define the try functionality in strict terms. If the member fails for any reason other than the well-defined try, the member must still throw a corresponding exception." So in fact Try methods can and should throw exceptions in some cases. – Andrew Arnott Apr 11 '17 at 20:52
134

(Corrected) There is official guideline, as Erik suggested.

When I see TrySomething method, I assume it

  • doesn't throw
  • returns bool
  • if I expect value, it is returned via 'out' parameter
  • there exists Something method, that allows me to handle any exception myself. (edit, suggested by Jesse Webb)
nothrow
  • 15,882
  • 9
  • 57
  • 104
  • 4
    Correction - It has official guideline. See Erik's answer. – nothrow Jun 20 '13 at 07:57
  • 10
    +1 But I also have a 4th expectation: If there is a `TryFoo` method, there will be a similar `Foo` method which allows me to handle any `` exceptions myself. These methods' signatures will likely be different so their usages are not interchangeable without other code changes. – Jesse Webb Jun 20 '13 at 17:11
  • 1
    @JesseWebb, thanks for pointing that out. I've added your comment into my answer, if you don't mind. – nothrow Jun 20 '13 at 19:26
  • 1
    "Doesn't throw" seems to me overgeneralized. For example, Int32.TryParse(String, NumberStyles, IFormatProvider, Int32) throws ArgumentException if it doesn't like the style parameter. – Jirka Hanika Nov 14 '18 at 10:11
  • 1
    I agree that "doesn't throw" could be considered overgeneralized, but I believe the intent was to convey that it doesn't throw as a result of execution rather than as a result of the value of the parameters. – ConfusingBoat Jun 12 '19 at 20:49
10

I think you should use try when you want to proceed. It doesn't matter that a method returns some value or not.

Case 1: if it returns fine, you can proceed in some way.

Case 2: if it does not return: it is still fine; you can proceed in some other way.

And if you expect some value as output of that method then use the out parameter.

Example

int value
if (dictionary.TryGetValue("key", out value))
{
    // Proceed in some way
}
else
{
    // Proceed in some other way
}
Community
  • 1
  • 1
Ashok Damani
  • 3,896
  • 4
  • 30
  • 48
6

You have to use "Try" in method name, when you want to manifest the fact that the method invokation can produce not valid result. Following the .NET standard it's, by the way, not a function that raises an exception, but the function that returns some VALID or NON_VALID, from the program perspective, value.

At the end, this all about naming convention you decide to use in your group.

Tigran
  • 61,654
  • 8
  • 86
  • 123
6

Make sure to include try in your methodname if:

  • you don't throw any exception
  • your method has the following signature: bool TrySomething(input, out yourReturn)

So basically if we use try-methods we only get a boolean result back.

So the following code will not throw any exceptions:

string input = "blabla";
int number;
if (int.TryParse(input, out number))
{
// wooohooo we got an int!
} else
{
//dooh!
}

Whereas this code can (and in this case will) throw exceptions:

string input = "blabla";
int number;
try
{
     number = int.Parse(input); //throws an exception
}
catch (Exception)
{
     //dooh!
}

Using Try methods is a safer and more defensive way to code. Also the code snippet #2 takes more performance to execute if it's not an integer.

Fabian Bigler
  • 10,403
  • 6
  • 47
  • 70
  • Your code snippet #2 should read `int number = int.Parse(input);` if you want it to be more meaningful in this context. – Pierre Arnaud Jun 26 '13 at 03:32
  • You are still missing the `int number;` declaration before the try block and the `number = ...` assignment. – Pierre Arnaud Jun 27 '13 at 07:59
  • @PierreArnaud Thank you, I also included 'int number' now. – Fabian Bigler Jun 27 '13 at 08:48
  • 1
    Note that you may still throw exceptions if the exception is somewhat unrelated to the direct action being performed, like `TryLoadFile(path, out file)` woah, out of RAM. So the caller would expect no errors for a bad path or access denied, but an exception for the whackier things that could also go wrong. And document it. – Luke Puplett Oct 29 '15 at 17:08
-2

Uncle Bob gives the example below in his book Clean Code. Whenever we expect an exception to be thrown we can use the Try prefix to a method name:

public void sendShutDown()
{
    try{
        tryToShutDown();
    } catch (DeviceShutDownError e) {
        logger.log(e);            
    }
}

And then (adapted):

private void tryToShutDown()
{
    //some code with no error handling, but
    //something might go wrong here
}

The tryToShutDown method does not make any error handling, because that's the responsibility of the sendShutDown method.

The TryParse pattern of Microsoft violates the clean code guideline that says that we should avoid output parameters.

If we're not developing a new version of C#, we don't have to stick to all Microsoft guidelines. Sometimes they're not the best.

Glauber
  • 25
  • 7
  • This answer provides good advice on what to do when Microsoft's Try-Parse pattern doesn't fit a case. It's too bad that methods named **Try...()** in .NET imply Try-Parse, because there are a lot of cases where something besides parsing needs to be tried. – Mike Grove aka Theophilus Nov 17 '21 at 19:31