The Try/Can-Pattern

I think this is a pattern (repeatedly implemented), although I have not seen it described anywhere yet.

Tell, don’t ask states, that you should trust the code you write. Instead of first asking if “he” can do it, or wants to do it, you just tell “him” to. Instead, it should throw an Exception, if it can’t satisfy the expectations of the caller.

An example for this is Stream.Write(…) or int.Parse(…). If you call the method, you expect it to function. If not, these methods will throw Exceptions.

But what, if you need to check, if a Stream is writable? Or what, if you’d expect the string to be invalid, and you want to respond to that without catching an exception?

This is, where Try/Can is often implemented. Examples for this are Stream.CanWrite, and int.TryParse.

The Try-Part

If it is often the case that a specific command won’t work, you can offer a alternative method that follows this convention:

 

bool TryMethodName(

          [method_parameters,]

          out return_type val)

 

The behavior is specified as follows:

  • TryMethodName should never throw the expected exceptions of  MethodName
  • The original return value should be exposed as an out-parameter.
  • TryMethodName should return a bool, if the operation succeeded or not

This is for example used by the Parse-Method in the .NET BCL:

class Int32 {
  ...
  int Parse(string text);
  bool TryParse(string text, out int val);
  ...
}

OrDefault as a Variation of Try

As a variation of TryMethodName, it can be useful to offer a MethodNameOrDefault. Here, instead of using bool and an output parameter, you’d return the CLR default value of MethodName’s return type, if the expectation stated by MethodName could not be satisfied.

 

return_type MethodNameOrDefault

                ([
method_parameters])

 

OrDefault is heavily used by LINQ:

class Linq.Enumerable {
  ...
  TSource ElementAt<TSource>(
        this IEnumerable<TSource> source, 
        int index);

  TSource ElementAtOrDefault<TSource>(
        this IEnumerable<TSource> source, 
        int index);
  ...
]

The Can-Part

Sometimes, you want to know, if something might work. For example, if you only want to show a button in the UI, if the action potentially can be executed.

 

bool CanMethodName([method_parameters])

// or 

bool CanMethodName { get; }

I’d favor a method over a property. Although a method implies, that it could be expensive to find out if MethodName can, or not.

The behavior is specified as follows:

  • The Can-property or –method should never throw any of the expected exceptions of MethodName
  • It should determine and return, if the method could be executed or if it can’t. Usually a positive return can’t guarantee, that, when really performing the action, it won’t fail.

Can is for example used by System.IO.Stream:

class Stream {
   ...
  int Read(byte[] buffer, int offset, int count);
  bool CanRead { get; }
  ...
}

Summary

Tell, don’t ask! is a very useful principle. It makes code better readable and it helps complying to SRP (Single Responsibility Principle). But sometimes you need more “weak” actions. Try/Can-Pattern helps accomplishing that, while maintaining encapsulation.

I’ll also post some example code on how to implement the pattern in C# soon.

14 thoughts on “The Try/Can-Pattern

    • Hi. Thanks for sharing the link. But tester/doer is different. Tester doer as described on your link, and also here (http://www.tbszone.com/post/2009/06/12/The-TesterDoer-pattern-and-the-TryParse-pattern.aspx) violates both “Tell, dont ask” and information hiding. The relation between ContainsKey and Get, or the relation between File.Exist and ReadAllLines is not obvious.

      Following “Try/Can” the actual test had to be performed inside the action subject. Also the method and the testmethod should exactly correlate by following the described convention.

      Also the Try, and the OrDefault part is not defined in tester/doer.

      I’m still looking for a better name including the OrDefault part.

      CanTryOrDefault-Pattern would be an option 🙂

  1. Hi Lars,

    quite an interesting blog post.

    Parts of what you are describing is known as the TryParse pattern and the Tester-Doer pattern. When dealing with code that routinely fails, these pattern are used to minimize performance issues (cf. http://msdn.microsoft.com/en-us/library/ms229009.aspx).

    Would you agree that you are proposing a combination of the TryParse pattern (the “try” part) and the Tester-Doer pattern (the “can” part)?
    If so, where do you see the benefits? Or in other words, I believe in patterns as reusable solutions to common problems. Which problem is solved by combining these patterns?

    Regards

    Sven-Torben

    • Hm. You are the second one. I never heard of them both. There are also just a few resources to be found.

      TryParse pattern is a very bad name. And tester/doer implies two responsibilities (see my previous answer).

      I also think more benefit will come with a code snippet that offers a generic solution for the “problem”.

      • I think the first time I heard about these patterns was while reading a book. Could be “Framework Design Guidelines”, but not sure.

  2. Pingback: Null – the most abused keyword in C#. « Matt Davey

  3. Pingback: Try Pattern - pro C# tology - devPortal

  4. CanTryOrDefault-Pattern looks like a nice name for this pattern. In any ways, the priority is to know how and when to use it and even if it’s a very simple pattern, not enough developer know it and use it. Thank you very much for sharing your knowledge.

  5. Pingback: KeyNotFoundException: The given key was not present in the dictionary | MAKOLYTE

  6. Pingback: Resolving cached NuGet packages at runtime – mikelimasierra.net

  7. Pingback: Advanced weapons of mass construction – mikelimasierra.net

Leave a comment