+4  A: 

(2) can be further composed, whilst (1) just runs. But neither are exactly "functional" as Action is not a function (compare with Func<A, R>).

So with (2) you could do:

Fault(someAction, Fault(firstTryFaultHandler, lastDitchFaultHandler))();

...and get expected behavior. That doesn't work with (1)

Craig Stuntz
Sorry, what do you mean "can be further composed"?
Carlo V. Dango
I added an example.
Craig Stuntz
A fault of a fault? Are we crossing the line between practice and theory here? :) Also I am wondering if one is more efficient than the other.
Carlo V. Dango
I could have written a more complicated (though perhaps more realistic) example using an entirely separate function (e.g., `IfThen`), but it seemed clearer to use the example in your question. Efficiency should be similar as in this case the expression is interpreted at compile time.
Craig Stuntz
@Carlo: get the variable from memory. If an exception occurs, find it on the local file system. If an exception occurs, notify the user.
xtofl
+3  A: 

The second case is like a Faultable Action Factory. Where you pass in a delegate of what you want to do, protectedBlock, and a delegate of what to do when an Exception occurs, faultHandler. The actions are returned wrapped in a try/catch structure as an aggregate Action. My problem with both these methods is no Exception is actually being caught so who ever is going to catch your throw has no information on which to act.

The difference in execution between the 2 is when they actually execute. The 1st will be executed when it's called. The 2nd will execute whenever the returned Action is called. I don't think the efficiency difference would be significant.

Sorax
First, I'm not sure I understand your problem? To me the Fault() is just a way of cleaning up the resources, not a way to define a re-try strategy. Speaking of which, I've found that in business applications, 99% of the time, you can't do much else than log the incident and show the error to the user.
Carlo V. Dango
@Carlo V. Dango: The try/catch doesn't clean up resources. Maybe you are thinking of a Using statement, which is equivalent to a try/catch/finally, where Dispose is called in the finally block. It's true you can't always do much. But without catching the Exception what are you going to log? Exception.message can often be very helpful.
Sorax
+1  A: 

In C#, approach 2 can be confusing. A caller might use "Fault(a, b);" expecting a and possibly b to be called. Instead, a lambda is created, returned and discarded. In other words nothing is done.

Regarding efficiency, approach 2 is a bit wasteful if most of your calls are of the form "Fault(a,b)();", i.e. you invoke the lambda immediately. In this situation, you don't need a lambda.

For these reasons, I would prefer approach 1. If you need to defer execution, you can introduce a lambda explicitly "() => Fault(a, b)".

Joh
Good point regarding understandability
Carlo V. Dango