Basic C# question if - else - c#

I was wondering if someone could tell me if this sample is correct please.
Please ignore the if statement i wrote it for demonstration purposes only.
basically what I want to know is, if I need to throw an exception in my else, is it right to have it return false then thrown an exception, like follows:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
return false;
throw new OutOfMemoryException();
}
}
OR - should I throw exception then return false outside else statement like this:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
throw new OutOfMemoryException();
}
return false;
}

Either of the following would make sense:
a) return the result of the test, don't throw:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException(j))
{
return true;
}
else
{
return false;
}
}
(Note that this example is overly verbose, and can be rewritten as:)
public bool test(Int j)
{
return !TestOnJThatcanThrowOutOfMemoryException(j)
}
b) throw if the test fails, do nothing otherwise:
public void test(Int j)
{
if(TestOnJThatcanThrowOutOfMemoryException(j))
{
throw new OutOfMemoryException();
}
}
In other words, make up your mind what that method is supposed to do - execute the test and return the result as a boolean value, or execute the test and throw when it fails.

When an exception occurs it does not execute the rest of the code in the method.
When a return statement is used it breaks the execution of the current method.
So you only need to call one of the two
i.e.
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
else
{
throw new OutOfMemoryException();
}
}

If you return false and then throw an exception than the exception will not be thrown. the method exits at the return statement.
if you throw an exception and then return false, then the exception will be thrown and caught in the appropriate catch block and your final return false will not execute.
So, if you want to throw an exception here, then throw the exception. If you want to return false here, return false.

In both cases, as is, only the first of the two will execute. Both return and throw cause execution to leave the function, so neither is technically correct.
In the first case, it will return, and the throw will never be called. In the second, the opposite is true (for the else block).
If you want an exception, throw it. Don't bother putting a return false anywhere.

The first example will never throw the exception as the return false ends the logic flow.
The second example the "return false;" will never be hit as either the return true; statement will be executed or the exception will be thrown.

In both of your examples you are doing something wrong. What do you want to achive?
In the first example throw statement will never be executed and in the second one return false won't be executed.

If you throw, the return statement won't get executed. All you need is:
public bool test(Int j)
{
if(!TestOnJThatcanThrowOutOfMemoryException E)
{
return true;
}
throw new OutOfMemoryException();
}

Your second option (just throwing the exception in the else) would be more correct. Note, though, that there is no code path to reach the return false; statement -- either the if is true, in which case true is returned, or its not, in which case an exception in thrown (thus aborting the code to the next-higher-level handler). So you don't really need it.

It appears that your attempt appears testing the value that comes to argument "int j".
The checking should fit in with a try catch,
try
{
// take a object as argument and try parse it to an int here
// or a TryParse will return a true/false if bool can return without exception.
int something = int.Parse(j);
}
catch (TestOnJThatcanThrowOutOfMemoryException e)
{
return true;
}
catch (OutOfMemoryException e)
{
// this will be hit if it isn't a TestOnJ.. exception
return false;
}
catch
{
// and here if not any of above
return false;
}
Though, i'm not sure if I ever would create a method which purpose would be just to force a specific kind of exception. Sorry if missunderstand you completely,

Go for the second option, but remove the "return false" statement at the end. Your method returns a boolean, so in case of an OutOfMemoryException (second if statement in your case), your method will not get a chance to pass a return value of false. But then this wont be an issue, if you handle the return value appropriately in the code which calls your method. A boolean is implicitly initialized to false, so in your calling function check if this method returned a true before you execute the remaining code.

Related

Multi checks in a try catch statement - is this okay?

Is there anything wrong with doing something like this? I am basically just trying to assert that these elements exist and if not then return false:
public static bool IsAllDataPresent()
{
try
{
Driver.Instance.FindElement(By.Id("id-a");
Driver.Instance.FindElement(By.Id("id-b");
Driver.Instance.FindElement(By.Id("id-c");
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
Is this is wrong then any help would be greatly appreciated. I am new to try catch.
If there is a method that tells you what you need to know without throwing, then call it.
If there is not, then you are in what I call a "vexing exception" situation. The best way out of that situation is to write the method that is missing.
public static bool IsPresent(string id)
{
try
{
Driver.Instance.FindElement(By.Id(id);
return true;
}
catch (NoSuchElementException)
{
return false;
}
}
And now your method is sensible:
public static bool IsAllDataPresent() =>
IsPresent("id-a") && IsPresent("id-b") && IsPresent("id-c");
Notice how when you write the correct abstraction, your method bodies get nice and concise.
For your specific question about checking multiple things and using try-catch... there's no problem with that, other than if it does fail, you're throwing away the exception which would tell you which of the things was missing.
In general, if you're expecting to find elements, you should wait for them to exist. If they exist right now, no waiting is done.
Example:
WebDriverWait wait = new WebDriverWait(Driver.Instance, new TimeSpan(0,0,5));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-a")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-b")));
wait.Until(ExpectedConditions.ElementExists(By.Id("id-c")));
return true;
If you don't wait, there's a risk you'll test the browser for an element which isn't there right now, but will exist in a few milliseconds time, and your script gives a premature, false negative, answer.
As you are trying to assert that these three elements exist and if not then return false you can optimize your code as per the code block below :
public static bool IsAllDataPresent()
{
if(Driver.Instance.FindElement(By.XPath("//*[#id='id-a' or #id='id-b' or #id='id-c']")).size() != 3)
{
Console.WriteLine("All the 3 elements exists")
return true;
}
else
{
Console.WriteLine("All the 3 elements doesn't exists")
return false;
}
}

Disable breaking code execution on exception

If i will write something like this:
void Code()
{
Console.WriteLine("a");
throw new Exception(); //the code will stop executing here
Console.WriteLine("b");
}
the code will stop executing after writing "a" to console. I am wondering, is it possible to execute whole function and then throw an exception? So if the exception will be thrown between Console.WriteLine("a"); and Console.WriteLine("b");, it will stop code execution, but i want the function to be executed fully before throwing an exception
Not really suggested at all, but i guess you could do something like this.
var errors = new List < Exception > ();
Console.WriteLine("a");
try {
ErrorThrowingMethod();
} catch (Exception e) {
errors.Add(e);
}
Console.WriteLine("b");
if (errors.Any()) throw new AggregateException(errors);
Simply put: No, you cant.
And shouldn't try to bend the programming logics to that way either.
An exception is the indication that something went terribly wrong and the function has to quit without a return value. That is the purpose of the exception, to indicate there was an error running the function and it COULDN'T COMPLETE execution.
void Code()
{
Boolean anyErrors = false;
Console.WriteLine("a");
anyErrors = true; // whenever something goes wrong.
Console.WriteLine("b");
if(anyErrors)
throw new Exception("There were errors doing whatever I was trying to.");
}
You can also in this case:
// will return false if it fails and true if succeeds.
Boolean Code()
{
Boolean anyErrors = false;
Console.WriteLine("a");
anyErrors = true; // whenever something goes wrong.
Console.WriteLine("b");
return !anyErrors;
}
Logics is the basis of programming, think logical and you won't have to fight the language.
You can do
void Code()
{
try
{
Console.WriteLine("a");
throw new Exception(); //the code will stop executing here
Console.WriteLine("b");
}
catch(Exception e)
{
Console.WriteLine("b");
throw new Exception(e.toString());
}
}
which will do what I think you are trying to achieve in this specific case, but as mentioned, often times it just doesn't make sense to try to continue because of dependency on events beforehand.

Why can I throw an exception after a return statement? [duplicate]

The code below will complain
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
throw e;
return false; // this will be flagged as unreachable code
}
whereas this will not:
try
{
session.Save(obj);
return true;
}
catch (Exception e)
{
return false;
throw e;
}
I dont get it...I thought my csc101 told me that return statements should always be the last statement in a function and that it exits the function and return control to the calling code. Why does this defy my professor's logic, and why does only one of these generate a warning?
return will exit the method; throw will also exit the method, assuming it is not inside the try. It can only exit once!
So regardless of the order - the first of the throw / return effectively end the method.
As more general feedback, though: if the intent is to return false upon failure, all you need is:
try
{
session.Save(obj);
return true;
}
catch
{
return false;
}
Personally, I would say that this is bad code - it hides the actual problem from the caller, making it very hard to debug. It tells us nothing of why it failed. I would say that the better approach is simply to let the exception bubble. In that case, there is no point returning true, because we would never return false - and there is no point catching an exception just to re-throw it. So the entire method becomes:
session.Save(obj);
(nothing else required whatsoever)
If your question is "why does only one of these generate a warning": a fair question, but the compiler isn't required to spot either of them for you. Perhaps it should spot it. I suspect that gmcs would spot this and warn about it - the compiler in mono is far more willing to point out stupidity.
Edit: as expected, [g]mcs outputs:
Program.cs(15,13): warning CS0162: Unreachable code detected
Program.cs(28,13): warning CS0162: Unreachable code detected
for the code below - so it does indeed report both uses as warnings:
class Program
{
static void Main() { }
static void DoSomething() { }
bool ReturnFirst()
{
try
{
DoSomething();
return true;
}
catch
{
return false;
throw; // line 15
}
}
bool ThrowFirst()
{
try
{
DoSomething();
return true;
}
catch
{
throw;
return false; // line 28
}
}
}
You are wrong: both your examples raise the Dead code compiler error because both throw and return mark the exit point of a method and no further code is allowed beyond that point.
However, whether the compiler allows it or not, the code below either the throw or the return is still dead and will never get a chance to execute.
(NOTE: this question was initially tagged as Java and my first sentence pertains to Java compiler semantics)
Because any code after the return statement within a code block will be unreachable.
This answer is based on C# and may or may not be applicable to Java.
In this case, you do not actually need the return statement. throw will be the last step of the function.
In this example, both return and throw will end the current function. Regardless of which way around you put them, then first will always prevent the second from being reachable.
NOTE: The exception to when a throw statement would end the function is if it was to be wrapped in a try block. In this case, the throw function would end execution of the remaining try block code, and move to the most relevant catch block - or finally block if a catch is not applicable.
Your code should look like this:
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e;
}
However, there is not much point in having the try/catch anyway if all you are doing is re-throwing the exception.
To specifically answer your only question:
Why does this defiles my professor's logic?
Well either your professor is wrong, or you have misunderstood them
The "return false;" in the catch block is unreachable because of the "throw e;" just before it. When the code executes in the catch block the first line is a throw which means you immediately throw the exception to the calling method and therefore any following code does not get executed.
try
{
session.Save(obj);
return true;
}
catch(Exception e)
{
throw e; //Throws exception to calling method
return false; //this will be flagged as unreachable code
}
I hope this helps.

Specifying that a function does not return in C#

Is there any way to tell the C# compiler that a function never returns? I'm running into the following problem. This is a boiled down version for simplicity.
public int myMethod()
{
try
{
return anythingHere();
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
'package.class.myMethod()' not all code paths return a value.
If not, is there a general way to frame this sort of thing other than inserting unreachable code? Having a 'return 0' or somesuch after the Exit just seems ridiculous to me. As far as I know there is no way that a function can return from an Environment.Exit call, so no return value is needed if that branch is taken (if it threw an exception the function still wouldn't need to have returned a value).
EDIT:
Maybe something like this?
public T MyExit<T>()
{
Environment.Exit(1);
return default(T);
}
Still not entirely satisfactory though.
C# does not support this.
In fact, it is impossible to do this in the general case.
Make the method void, and pass in an object that contains the 'anythingHere' type of information you need as an out type, so that it can be set, but the method itself won't actually return anything.
public void myMethod(out anythingObject)
{
try
{
anything = new anythingObject(stuff goes here);
}
catch
{
Environment.Exit(1); //or a function which always either calls Environment.Exit or throws an exception
}
}
I'm not sure if it's what you're looking for, but this would avoid unreachable code:
public int myMethod()
{
int retVal = 0;
try {
retVal = anythingHere();
} catch {
Environment.Exit(1);
}
return retVal;
}
It might be better to throw an exception than to call Environment.Exit. If someone else used your class, and their process suddenly shut down, they'd be pretty surprised. By throwing an exception you can at least explain why the problem happened.
At the top level entry point of your app (i.e., Main) you could then set up a global exception handler (AppDomain.UnhandledException) that handles all exceptions and calls Environment.Exit.
Make it a void, instead of an int.
public void myMethod(out int i)
{
try
{
i = anythingHere();
}
catch
{
Environment.Exit(1);
}
}

C# Function cannot return -- prevent compiler warning

I have a function that is guaranteed never to return. It logs data and throws an exception.
public int f()
{
... do stuff ...
if(condition)
BadUserData.Throw(... parameters...);
else
return 0;
}
I get the error message "not all code paths return a value. I can fix this of course by a dummy return after the non returning function, but I wonder if there is an attribute or something I can apply to the Throw function it indicate that it never returns? I had a look and could not find one.
No, there isn't. Actually, to get the most appropriate call stack, I would have something more like below, where the method creates the exception but we throw it locally:
if(condition)
throw BadUserData.CreateSomeFormOfException(... parameters...);
which solves both problems in one go.
Another lazier approach would be:
if(condition) {
// throws <===== comments are important here ;p
BadUserData.Throw(... parameters...);
}
return 0;
Well instead of BadUserData.Throw actually throw:
public int f()
{
... do stuff ...
if(condition)
throw new Exception("... parameters...");
else
return 0;
}
or have this method return an Exception and then:
throw BadUserData(... parameters...);
Other than that, no, there aren't any attributes or anything that will make your code to compile.
If the method's job is to log and then throw and exception, you sould change the method signature to be
public void f()
instead of
public int f()
This will take care of your compiler issue. It's also going to be a lot cleaner as you can omit the else section of the method body.
Return the exception in BadUserData.Throw instead of throwing it and do:
public int f()
{
... do stuff ...
if(condition)
throw BadUserData.Throw(... parameters...);
else
return 0;
}
I guess you have no other choice than adding a return statement with a dummy value, e.g. return -1;.

Categories