C# Function cannot return -- prevent compiler warning - c#

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;.

Related

C# Extension Methods for Generic Functions

I want to create a simple one-line try/catch without all the extra fluff:
// The extension class
public static class TryExFunc
{
public static Exception TryEx<TResult> (this Func<TResult> func,
out TResult result)
{
Exception error = null;
try
{
result = func();
}
catch(Exception ex)
{
error = ex;
result = default(TResult);
}
return error;
}
}
// My Error Prone Function
public string SayHello() { throw new Exception(); }
// My Code
// One (ok, two) line(s) to try/catch a function call... ew, works, but ew
string result;
Exception error = ((Func<string>)SayHello).TryEx<string>(out result);
// I want to do this!!!
string result;
Exception error = SayHello.TryEx<string>(out result);
Is there a way that I can do the bottom example? I'm still learning C# (coming from Lua and C++ background). Lua has a really nice function called 'pcall' that basically does the same thing. Thanks for any advice or suggestions you have!
:)
You can't. Because the method group has no type. It's convertible to different delegate types. So you have to cast it to a delegate type before using it.
If you want to avoid cast you can do:
Func<string> sayHello = SayHello;
Exception error = sayHello.TryEx<string>(out result);
It doesn't work as an extension method because in order to use an extension method, C# first needs to know the type to extend and, as #Selman22 stated, SayHello is a method group which may have other overloads, so we don't know the type.
It works as a method call because C# can see that the parameter required is a Func<T> and that SayHello is a valid Func<T>
The format below works to call the function.
string result;
Exception error = TryExFunc.TryEx(SayHello, out result);
and I do agree with #Enigmativity that you probably shouldn't be treating exceptions this way.

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);
}
}

Catch and Continue

I want an extension method or generic method where I want code execution to continue even there is some exception and keep recording the exceptions in a list. This is an example what I tried
public void ValidateName()
{
if (_customer.Name.Length < 5)
throw new Exception("shortname");
}
public void ValidateAge()
{
if (_customer.Age < 5)
throw new Exception("short age");
}
internal void Validate()
{
this.CatchAndContinue(delegate()
{
this.ValidateName(); // throws exception and add to list
this.ValidateAge(); // but this should also execute
});
}
public void CatchAndContinue(Action action)
{
try
{
action();
}
catch (Exception ex)
{
exceptions.Add(ex);
}
}
For current class I can pass exceptions to ValidateName and ValidateAge method, but I want if we can do the way I want, with little change in validate() method body. I know semantically it sounds weired but I need lot of places to do this. Or if there is something better to achieve it
EDIT
This validation is simple example, not in all scenerio it will be validator only. By the way in this case I want to provide UI the list of errors and why throw, because when model constructed from DB (due to wrong data in DB) such objects should not be created. These are just examples of concern
Don't use exceptions for control flow.
Instead, your validate method should return a bool, and let the client of the validate method decide what to do. One step beyond that is return a ValidationResult with a ValidationStatus property that indicates success or failure and a Message property that records the reason that validation failed.
Yield / return may be useful to you.
http://msdn.microsoft.com/en-us/library/9k7k7cf0%28v=vs.80%29.aspx
Does it have to be exceptions?
To clarify:
internal IEnumerable<string> Validate()
{
if( _customer.Age > 5 ) { yield return "Too Old"; }
if( _customer.Name.Length < 3 ) { yield return "Not enough name characters"; }
}
// using it
IEnumerable<string> errors = myCustomer.Validate();
if( errors.Length > 0 ) {
// uh oh, print out the errors!
foreach( string error in errors ) {
MsgBox(error);
}
}
Instead of throwing exceptions in the Validate methods, I would add to the exceptions list and return a bool value indicating success/failure (return part is optional, add it only if you care about the status of validation).
Something like:
public void ValidateName()
{
if (_customer.Name.Length < 5) {
LogValidationFailure("shortName"); // you can add more params if needed
return; // or return false if you need it
}
// do normal business here
}
Not only is this cleaner, it is better performing since try/catch and exception throwing are expensive.

if statement for throwing Exception?

Hi I wanted to ask because I'm not sure if is it propriete using of Exception:
public int Method(int a, int b) {
if(a<b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff...
}
can I throw Exception after if statement? or should I always use try - catch when it goes with the exceptions?
That is perfectly valid. That is exactly what exceptions are used for, to check for "Exceptions" in your logic, things that weren't suppose to be.
The idea behind catching an exception is that when you pass data somewhere and process it, you might not always know if the result will be valid, that is when you want to catch.
Regarding your method, you don't want to catch inside Method but infact when you call it, here's an example:
try
{
var a = 10;
var b = 100;
var result = Method(a, b);
}
catch(ArgumentException ex)
{
// Report this back to the user interface in a nice way
}
In the above case, a is less than b so you can except to get an exception here, and you can handle it accordingly.
In this case, you don't want to catch the exception. You're throwing it to alert the caller that they've made a mistake in the way they called your method. Catching it yourself would prevent that from happening. So yes, your code looks fine.
That's perfectly fine. You're throwing the exception, not catching/handling it, so you wouldn't need a try/catch block for it.
This is perfectly valid, you can use the same construct even with the constructors.
But What you should not do is
public int Method(int a, int b)
{
try
{
if (a < b)
throw new ArgumentException("the first argument cannot be less than the second");
}
catch (Exception)
{
}
return 0;
}
You've got the right idea. You could use your code like this:
void MyMainMethod()
{
// ... oh, let's call my Method with some arguments
// I'm not sure if it'll work, so best to wrap it in a try catch
try
{
Method(-100, 500);
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
public int Method(int a, int b)
{
if (a < b) throw new ArgumentException("the first argument cannot be less than the second");
//do stuff ... and return
}
It might help to look through MSDN's Handling and Throwing Exceptions and Best Practices for Handling Exceptions
What you've done here is perfectly Ok.
A common pattern for arg checks is to wrap the check/throw code in a static "Contract" class ensuring you have a consistent approach to exception management when validating input arguments.
Slightly off topic but if using .NET 4.0 you can also look at the new Code Contracts feature for validation of method input and output.
All above answers are correct but I like to mention one additional point here which I did not see mentioned in any of the answers. The reason why you should throw an exception and not return an integer e.g. 0 or -1 for signalling that an error occurred, is that the returned integer can be mistakenly treated/assumed as a valid result of your method. It is an integer anyway, and your method, after performing its internal logic returns an integer. So the caller of this method can mistakenly treat any returned integer as a valid result, which can lead to bugs down the line. In that case, throwing an exception makes perfect sense.

Basic C# question if - else

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.

Categories