Hello StackOver Community,
I have the following c#-code
void foo(int x)
{
if(x<=0)
{
return;
}
do something more...
.
.
.
}
I want to get rid of the if statement by calling a function which will "return" my foo function if the condition x<= 0 is met.
That is
void foo(int x)
{
TerminateIfNegative(x);
do something more...
.
.
.
}
private ???? TerminateIfNegative(int a)
{
if (a<=0)
{
"Make the method which called me "return" at the place I was called"
}
}
I hope it is somehow clear what I want to do. Does someone have an idea?
Cheers,
Florian
When a method's return type is void, this method does not return anything. There are only the following options to stop the execution of commands inside a void method:
Throw an exception
Use return; (which is the most common way)
If a negative value should not be passed as an argument to your method, then it is valid to throw an exception and document that, in order callers of this method to be aware of this from the very beggining.
The behaviour you´re asking for is common in procedural programming where you have a common linear program-flow from the very first line to the very last. This will apply to a line-by-line execution, which isn´t what OOP is about. There are good reasons we usually discourage use of goto and other stuff that controls program-flow as it will make it very hard to follow your code, e.g. when debugging. In fact this leads to spaghetti-code.
Imagine you want to debug your app in a few months. You step through your code until you reach Foo, step into it to sea what it does and - woaah, what is this - your debuger jumps out of Foo for whatever reason. It´s completely unclear why the method simply stops its execution.
What you seem to want actually is performing some checks on your user-input. So if your user types in a negative number your program should stop. It´s pure fine to throw an exception in this case, which basically indicates that a method cannot do what it is supposed to do. You could just create some Validate-method that throws an exception on ivalid input:
void Validate(int x)
{
if(x <= 0)
throw new InvalidArgumentException("x must not be negative");
}
This leaves it to the caller of the method how to handle an error. This way your Validate-method just validates the input. It should not terminate the calling method, which would break the single-responsibility-principle, wouldn´t it?
However throwing an exception in your case seems a bit like taking a a sledgehammer to crack a nut. The most simple and cleanest way is to do exactly what you want to avoid. Have an if-statement that terminates foo if the input is invalid:
void foo()
{
if(!Validate(x))
return;
}
bool Validate(int x)
{
return x > 0;
}
Actually there is a solution for this. And a pretty ugly one.
I'm aware that probably nobody will agree that this should be used, but I will present it anyway. Here you have the infamous goto solution:
void foo(int x)
{
TerminateIfNegative(x);
do something more...
.
.
.
EndOfFoo:
}
private void TerminateIfNegative(int a)
{
if (a<=0)
{
goto EndOfFoo;
}
}
Related
Because I am writing my first MVVM application and I never write so "big" application. I have no idea how error handling for users is normally done.
I found some "guide":
http://codebuild.blogspot.co.at/2012/01/15-best-practices-about-exception.html
At first point is mentioned: "Don't manage business logic with exceptions. Use conditional statements instead. If a control can be done with if-else statement clearly, don't use exceptions because it reduces readability and performance (e.g. null control, divide by zero control)."
So is better to use if-else statment? Or how do you do? Or is better only working with try-catch statment?
And later when I have more if-else code statments one in other .. is better to use basic error bool and error string for all over the code? When happend just turning this bool to true state and write message to error string? And later by showing result check if any error happend?
If you dont understand the question please ask, or write how do you handle with errors in code for user?
Any general guide will be welcome :)
As mentioned exceptions decrease performance (not sure about readability, I personally never had a problem with that). If you compare how long it takes to check something with IF statement or with TRY-CATCH, you will notice a huge difference in favor of the first one.
I would say use IF statement everywhere, where you can check validity yourself - if it fails, in else statement you can specify what needs to be done (display message to user etc.). For example when dividing x/y
private static void IfMethod()
{
int x = 10;
int y = 0;
if (y != 0)
{
Console.WriteLine(x / y);
}
else
{
Console.WriteLine("y is 0");
}
}
Try-catch is more for situations where you can't predict everything. For example if you are trying to read/write a file you will never for 100% know if you have access to that particular file, the file system or if the file actually exist. This is especially true if you are writing applications for someone else. You have no way to know how they configured their PC, access rights etc.
Hope this helps.
Don't manage business logic with exceptions. Use conditional
statements instead. If a control can be done with if-else statement
clearly, don't use exceptions because it reduces readability and
performance
True. But let's clarify, what is meant here.
This is a sample, when logic is built on exceptions:
private int? Foo(int a)
{
try
{
// bar is some int field
return bar / a;
}
catch (DivideByZeroException)
{
return null;
}
}
Here, method Foo expects, that a can be 0. Hence, a == 0 isn't an exception. But, instead of this:
private int? Foo(int a)
{
if (a == 0)
return null;
return bar / a;
}
the logic of this method uses an exception to detect, that result of the method is undetermined, and returns special value (null).
On the other hand, here's sample, when you must use exception:
public int Foo(int a)
{
if (a == 0)
throw new ArgumentOutOfRangeException("a can't be 0!");
return bar / a;
}
This version of Foo is a public method from class library. The logic of Foo can't handle the case, when a == 0. So, it must check input parameter, and throw exception.
To re-phrase citation above:
do not throw exceptions, if current state can (and must) be handled by your business logic; use conditional statements instead.
do throw exceptions, if current state is unexpected, and cannot (must not) be handled by your business logic.
I'm starting to use Code Contracts, and whilst Contract.Requires is pretty straight forward, I'm having trouble seeing what Ensures actually does.
I've tried creating a simple method like this:
static void Main()
{
DoSomething();
}
private static void DoSomething()
{
Contract.Ensures(false, "wrong");
Console.WriteLine("Something");
}
I never see the message "wrong" though, nor does it throw exceptions or anything else.
So what does it actually do ?
It's odd for it to not throw anything - if you're running the rewriter tool with the appropriate settings. My guess is that you're running in a mode which doesn't check postconditions.
The confusing thing about Contract.Ensures is that you write it at the start of the method, but it executes at the end of the method. The rewriter does all the magic to make sure it executes appropriately, and is given the return value if necessary.
Like many things about Code Contracts, I think it's best to run Reflector on the results of the rewriter tool. Make sure you've got the settings right, then work out what the rewriter has done.
EDIT: I realise I haven't expressed the point of Contact.Ensures yet. Simply put, it's to ensure that your method has done something by the end - for example, it could ensure that it's added something to a list, or (more likely) that the return value is non-null, or positive or whatever. For example, you might have:
public int IncrementByRandomAmount(int input)
{
// We can't do anything if we're given int.MaxValue
Contract.Requires(input < int.MaxValue);
Contract.Ensures(Contract.Result<int>() > input);
// Do stuff here to compute output
return output;
}
In the rewritten code, there will be a check at the point of return to ensure that the returned value really is greater than the input.
I have a system where the employeeId must alway exist unless there is some underlying problem.
The way I see it, is that I have two choices to check this code:
1:
public void GetEmployee(Employee employee)
{
bool exists = EmployeeRepository.VerifyIdExists(Employee.Id);
if (!exists)
{
throw new Exception("Id does not exist");
}
}
or 2:
public void GetEmployee(Employee employee)
{
EmployeeRepository.AssertIfNotFound(Employee.Id);
}
Is option #2 acceptable in the C# language?
I like it because it's tidy in that i don't like looking at "throw new Exception("bla bla bla") type messages outsite the class scope.
As a rule, you should only throw exceptions in exceptional circumstances. Since this one such circumstance, throwing an exception is the right thing to do.
It depends what you mean by Assert.
You could use Debug.Assert (or Trace.Assert if you want it to also work in release mode). However this is not that useful because it halts the program and pops up a dialog box until a user presses something. This isn't so good for an unmonitored system. So I'd recommend throwing instead in most cases though as you can decide how you want to react to the error - stop the program, or just log and try to continue.
But if we assume that your Assert method checks its argument and possibly throws an exception, then yes I think that's a good way of doing it.
In fact to pick an example, in Jon Skeet's morelinq both methods are used. For example here:
public static IEnumerable<TSource> AssertCount<TSource>(
this IEnumerable<TSource> source,
int count,
Func<int, int, Exception> errorSelector)
{
source.ThrowIfNull("source");
if (count < 0) throw new ArgumentException(null, "count");
errorSelector.ThrowIfNull("errorSelector");
return AssertCountImpl(source, count, errorSelector);
}
Use exceptions, its what they are there for - exceptional circumstances.
All the standard .NET libraries use this method of handling such circumstances so takes your cues from Microsoft.
The idea behind assertions, as I've always used them, are that they are instant feedback when running a debug build. Kind of an in your face that something happened. Or logged to file if the app is setup that way.
Exceptions are used to handle exceptional behavior, as noted above.
What I do, especially early in projects life cycle might be something like:
public void GetEmployee(Employee employee)
{
bool exists = EmployeeRepository.VerifyIdExists(Employee.Id);
Debug.Assert( exists, "employee does not exist for id: " + Employee.Id );
if (!exists)
{
throw new Exception("Id does not exist);
}
}
Perhaps refractoring out the Debug.Assert once the initial hiccups are dealt with.
Imagine the following code:
void DoThis()
{
if (!isValid) return;
DoThat();
}
void DoThat() {
Console.WriteLine("DoThat()");
}
Is it OK to use a return inside a void method? Does it have any performance penalty? Or it would be better to write a code like this:
void DoThis()
{
if (isValid)
{
DoThat();
}
}
A return in a void method is not bad, is a common practice to invert if statements to reduce nesting.
And having less nesting on your methods improves code readability and maintainability.
Actually if you have a void method without any return statement, the compiler will always generate a ret instruction at the end of it.
There is another great reason for using guards (as opposed to nested code): If another programmer adds code to your function, they are working in a safer environment.
Consider:
void MyFunc(object obj)
{
if (obj != null)
{
obj.DoSomething();
}
}
versus:
void MyFunc(object obj)
{
if (obj == null)
return;
obj.DoSomething();
}
Now, imagine another programmer adds the line: obj.DoSomethingElse();
void MyFunc(object obj)
{
if (obj != null)
{
obj.DoSomething();
}
obj.DoSomethingElse();
}
void MyFunc(object obj)
{
if (obj == null)
return;
obj.DoSomething();
obj.DoSomethingElse();
}
Obviously this is a simplistic case, but the programmer has added a crash to the program in the first (nested code) instance. In the second example (early-exit with guards), once you get past the guard, your code is safe from unintentional use of a null reference.
Sure, a great programmer doesn't make mistakes like this (often). But prevention is better than cure - we can write the code in a way that eliminates this potential source of errors entirely. Nesting adds complexity, so best practices recommend refactoring code to reduce nesting.
Bad practice??? No way. In fact, it is always better to handle validations by returning from the method at the earliest if validations fail. Else it would result in huge amount of nested ifs & elses. Terminating early improves code readability.
Also check the responses on a similar question: Should I use return/continue statement instead of if-else?
It's not bad practice (for all reasons already stated). However, the more returns you have in a method, the more likely it should be split into smaller logical methods.
The first example is using a guard statement. From Wikipedia:
In computer programming, a guard is a
boolean expression that must evaluate
to true if the program execution is to
continue in the branch in question.
I think having a bunch of guards at the top of a method is a perfectly understandable way to program. It is basically saying "do not execute this method if any of these are true".
So in general it would like this:
void DoThis()
{
if (guard1) return;
if (guard2) return;
...
if (guardN) return;
DoThat();
}
I think that's a lot more readable then:
void DoThis()
{
if (guard1 && guard2 && guard3)
{
DoThat();
}
}
There is no performance penalty, however the second piece of code is more readable and hence easier to maintain.
In this case, your second example is better code, but that has nothing to do with returning from a void function, it's simply because the second code is more direct. But returning from a void function is entirely fine.
It's perfectly okay and no 'performance penalty', but never ever write an 'if' statement without brackets.
Always
if( foo ){
return;
}
It's way more readable; and you'll never accidentally assume that some parts of the code are within that statement when they're not.
I'm going to disagree with all you young whippersnappers on this one.
Using return in the middle of a method, void or otherwise, is very bad practice, for reasons that were articulated quite clearly, nearly forty years ago, by the late Edsger W. Dijkstra, starting in the well-known "GOTO Statement Considered Harmful", and continuing in "Structured Programming", by Dahl, Dijkstra, and Hoare.
The basic rule is that every control structure, and every module, should have exactly one entry and one exit. An explicit return in the middle of the module breaks that rule, and makes it much harder to reason about the state of the program, which in turn makes it much harder to say whether the program is correct or not (which is a much stronger property than "whether it appears to work or not").
"GOTO Statement Considered Harmful" and "Structured Programming" kicked off the "Structured Programming" revolution of the 1970s. Those two pieces are the reasons we have if-then-else, while-do, and other explicit control constructs today, and why GOTO statements in high-level languages are on the Endangered Species list. (My personal opinion is that they need to be on the Extinct Species list.)
It is worth noting that the Message Flow Modulator, the first piece of military software that EVER passed acceptance testing on the first try, with no deviations, waivers, or "yeah, but" verbiage, was written in a language that did not even have a GOTO statement.
It is also worth mentioning that Nicklaus Wirth changed the semantics of the RETURN statement in Oberon-07, the latest version of the Oberon programming language, making it a trailing piece of the declaration of a typed procedure (i.e., function), rather than an executable statement in the body of the function. His explication of the change said that he did it precisely because the previous form WAS a violation of the one-exit principle of Structured Programming.
While using guards, make sure you follow certain guidelines to not confuse readers.
the function does one thing
guards are only introduced as the first logic in the function
the unnested part contains the function's core intent
Example
// guards point you to the core intent
void Remove(RayCastResult rayHit){
if(rayHit== RayCastResult.Empty)
return
;
rayHit.Collider.Parent.Remove();
}
// no guards needed: function split into multiple cases
int WonOrLostMoney(int flaw)=>
flaw==0 ? 100 :
flaw<10 ? 30 :
flaw<20 ? 0 :
-20
;
Throw exception instead of returning nothing when object is null etc.
Your method expects object to be not null and is not the case so you should throw exception and let caller handle that.
But early return is not bad practice otherwise.
I'm looking for an "elegant" way to suppress exceptions when calling a method.
I think the following code is way too verbose:
try
{ CallToMethodThatMayFail(3); }
catch {}
Is there some syntactic sugar I can use to say "I don't really care if this method fails"? I want to call the method and continue execution regardless of what happens with the method.
It is rarely a good idea to ignore/swallow errors...
To allow re-use, the only option you have is something like a method that takes an Action:
static void IgnoreErrors(Action action) {try {action();} catch {}}
But you haven't exactly saved much by the time you've done:
SomeHelper.IgnoreErrors(() => CallToMethodThatMayFail(3));
I'd just leave the try/catch in place...
Re the question in the comment:
static void IgnoreErrors<T>(Action action) where T : Exception
{
try { action(); } catch (T) {}
}
SomeHelper.IgnoreErrors<ParseException>(() => CallToMethodThatMayFail(3));
but I would still find it clearer to have the try/catch locally...
Nope this is it.
And it's a good thing it's verbose. If you're suppressing a possible exception you better have a very good reason. The verbosity will help you or the next person who looks at the code in a few months.
Using Castle, you could do something like this:
public class ExceptionSuppressionInterceptor : Castle.Core.Interceptor.IInterceptor
{
public void Intercept(IInvocation invocation)
{
try {
invocation.Proceed();
}
catch (Exception ex) {
// Suppressed!
}
}
}
And decorate the class you want to suppress exceptions for like this:
[Interceptor(typeof(ExceptionSuppressionInterceptor))]
public class GoodPracticeBreaker {
}
But you really probably shouldn't.
I don't know of anything more terse. I suppose you could do some AOP or similar for something more fancy.
The .Net convention is that classes implement a TryCallMayFail() method and a CallMayFail() method and the caller chooses which one to uses but the TryCallMayFail() method would include exactly what you have there.
No, there's no better way to do this, and there's a good reason for it. The exception you see may mean more than "the method failed". It may mean, "the system is failing".
You probably should at least log the fact of the failure, in case it turned out to be important after all.
Why do you say this is too verbose? If you are trying to save keystrokes, you can just use a code snippet. If you are concerned about readability, then I think that an AOP method would be less clear to another maintainer (at least initially) and for me, this outweighs the verbosity.