try/catch + using, right syntax - c#

Which one:
using (var myObject = new MyClass())
{
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
}
OR
try
{
using (var myObject = new MyClass())
{
// something here...
}
}
catch(Exception ex)
{
// Handle exception
}

I prefer the second one. May as well trap errors relating to the creation of the object as well.

Since a using block is just a syntax simplification of a try/finally (MSDN), personally I'd go with the following, though I doubt it's significantly different than your second option:
MyClass myObject = null;
try
{
myObject = new MyClass();
//important stuff
}
catch (Exception ex)
{
//handle exception
}
finally
{
if (myObject is IDisposable)
{
myObject.Dispose();
}
}

It depends. If you are using Windows Communication Foundation (WCF), using(...) { try... } will not work correctly if the proxy in using statement is in exception state, i.e. Disposing this proxy will cause another exception.
Personally, I believe in minimal handling approach, i.e. handle only exception you are aware of at the point of execution. In other word, if you know that the initialization of a variable in using may throw a particular exception, I wrap it with try-catch. Similarly, if within using body something may happen, which is not directly related to the variable in using, then I wrap it with another try for that particular exception. I rarely use Exception in my catches.
But I do like IDisposable and using though so I maybe biased.

If your catch statement needs to access the variable declared in a using statement, then inside is your only option.
If your catch statement needs the object referenced in the using before it is disposed, then inside is your only option.
If your catch statement takes an action of unknown duration, like displaying a message to the user, and you would like to dispose of your resources before that happens, then outside is your best option.
Whenever I have a scenerio similar to this, the try-catch block is usually in a different method further up the call stack from the using. It is not typical for a method to know how to handle exceptions that occur within it like this.
So my general recomendation is outside—way outside.
private void saveButton_Click(object sender, EventArgs args)
{
try
{
SaveFile(myFile); // The using statement will appear somewhere in here.
}
catch (IOException ex)
{
MessageBox.Show(ex.Message);
}
}

Both are valid syntax. It really comes down to what you want to do: if you want to catch errors relating to creating/disposing the object, use the second. If not, use the first.

There is one important thing which I'll call out here: The first one will not catch any exception arising out of calling the MyClass constructor.

From C# 8.0 on, you can simplify using statements under some conditions to get rid of the nested block, and then it just applies to the enclosing block.
So your two examples can be reduced to:
using var myObject = new MyClass();
try
{
// something here...
}
catch(Exception ex)
{
// Handle exception
}
And:
try
{
using var myObject = new MyClass();
// something here...
}
catch(Exception ex)
{
// Handle exception
}
Both of which are pretty clear; and then that reduces the choice between the two to a matter of what you want the scope of the object to be, where you want to handle instantiation errors, and when you want to dispose of it.

If the object you are initializing in the Using() block might throw any exception then you should go for the second syntax otherwise both the equally valid.
In my scenario, I had to open a file and I was passing filePath in the constructor of the object which I was initializing in the Using() block and it might throw exception if the filePath is wrong/empty. So in this case, second syntax makes sense.
My sample code :-
try
{
using (var obj= new MyClass("fileName.extension"))
{
}
}
catch(Exception ex)
{
//Take actions according to the exception.
}

From C# 8.0, I prefer to use the second one same like this
public class Person : IDisposable
{
public Person()
{
int a = 0;
int b = Id / a;
}
public int Id { get; set; }
public void Dispose()
{
}
}
and then
static void Main(string[] args)
{
try
{
using var person = new Person();
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType == System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Constructor Person");
}
catch (Exception ex) when
(ex.TargetSite.DeclaringType.Name == nameof(Person) &&
ex.TargetSite.MemberType != System.Reflection.MemberTypes.Constructor)
{
Debug.Write("Error Person");
}
catch (Exception ex)
{
Debug.Write(ex.Message);
}
finally
{
Debug.Write("finally");
}
}

Related

How can i send a variable from a method to the catch block of that caller's method in c#?

Let's say I have a method like this.
Boolean hasErrors = false;
try
{
var anotherId = DoSomethingWithList(list);
}
catch (Exception ex)
{
errorMessageDetail.Text = ex.Message;
hasErrors = true;
}
And In my DoSomethingWithList method I am doing fancy stuff in an iteration.
public Guid? DoSomethingWithList(List<ofthings> myList)
{
foreach (var member in myList)
{
//Do fancy and dangerous stuff in here.
}
}
What I try to achieve is that, When I get an exception in DoSomethingWithList method I also want to know in which member of the list this exception has been thrown, and include it in errorMessageDetail. Thank you in advance.
Edit: I can not simply move my exception block into the loop itself because errorMessageDetail is connected with the aspx in the front end, and my DoSomethingWithList method is in my Business Layer.
You could create your specific exception type. E.g.
public Guid? DoSomethingWithList(List<ofthings> myList)
{
foreach (var member in myList)
{
try
{
//Do fancy and dangerous stuff in here.
}
catch (Exception ex)
{
throw new ListProcessingException(member, ex);
}
}
}
Try this.
public Guid? DoSomethingWithList(List<ofthings> myList){
foreach (var member in myList){
try{
//Do fancy and dangerous stuff in here.
}
catch(Exception e){
throw new Exception(string.Format("{0} thrown by {1}", e.Message, member.ToString()), e);
}
}
I'm assuming member has a suitable implementation of ToString(), otherwise just use whatever property is relevant.
the only way to return state from DoSomethingWithList in case of error is to wrap its functionality in another try catch as #Stefan Steinegger said.
because if you dont catch the exception the (thread / callstack) will be killed and thus stack frames will be dead.
(stack frame is where locals are stored)

Are there any issues with using block for an IDisposable within a try catch block?

The MSDN recommends putting any instantiation of classes that implement IDisposable into a using block. Or alternatively, if it is being instantiated within a try-catch block, then Dispose in Finally.
Are there any problems with using a using block within a try-catch block like so?
try
{
using (Foo bar = new Foo())
{
bar.doStuff();
}
}
catch (Exception e)
{
//vomit e
}
Of course I can just call Dispose in a Finally block, but I'm a newbie to programming and I'm just curious to know if doing something like this is practically acceptable or if someone would smack me up the back of my head and yell at me that I'm Doing-It-Wrong™.
Or rather, I'm more interested in knowing why this would be wrong if it is.
No, that looks perfectly fine. Your bar instance will be disposed before you even get into the catch block.
This is... drum roll... absolutely fine.
The only issue is that you shouldn't use catch (Exception), but catch the specific errors you're interested in (even if this is just an example), but that has no bearing on the using. In fact, the only reason why you would put the using outside the try block is because you want to continue doing something with bar that's unrelated to the code that failed -- otherwise, keeping the scope as small as possible is generally a good idea.
It is OK but you lost access to object that would have caused the exception in the exception.
And catching general exceptions is not considered a good practice
Foo bar = null;
try
{
bar = new Foo();
bar.doStuff();
}
catch (IndexOutOfRangeException e)
{
//vomit e
Debug.WriteLine(e.msg);
if(bar == null)
Debug.WriteLine("bar = new Foo() failed ");
else
Debug.WriteLine("bar fail ID = " + bar.ID);
}
catch (Exception e)
{
// ...
// unless you are going to handle it gracefully you should rethrow it
}
finally
{
if(bar != null) bar.Dispose();
}
Your example code is redundant. The Using() documentation states:
A using statement of the form
using (ResourceType resource = expression)
statement corresponds to one of two possible expansions. When ResourceType is a value type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}
Otherwise, when ResourceType is a reference type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
In either expansion, the resource variable is read-only in the embedded statement.
Your code will ultimately look something like:
try
{
Foo bar = new Foo()
try
{
bar.doStuff();
}
finally
{
if (bar != null) ((IDisposable)bar).Dispose();
}
}
catch (Exception e)
{
//vomit e
}
No real reason for two try statements. It's not wrong code, it's just redundant in the context of multiple try statements. You question appears to be about Disposing of an object. In this context, it is redundant. If you are also concerned about the object constructor throwing an exception, the obviously this would be needed.
Are there any problems with using a using block within a try-catch block like so?
No, I write your example all the time.
Of course I can just call Dispose in a Finally block,
Sort of, the constructor must be called outside the try/catch, otherwise the variable will be out of scope by the time you reach the finally block
valid:
var foo = new bar();
try
{
}
finally
{
foo.Dispose();
}
invalid:
try
{
var foo = new bar();
}
finally
{
foo.Dispose();
}
No, it is fine, but if you want to access bar during the catch, you'll need an inner try catch:
try
{
using (Foo bar = new Foo())
{
try
{
bar.doStuff();
}
catch (Exception e)
{
//vomit e, with bar available.
}
}
}
catch (Exception e)
{
//vomit e, relating to a problem during creation of Foo.
}
or, as suggested in the comments, factor out the inner block into a new method.

How to rethrow a prior exception from inside a nested try-catch block? (C#)

I have code that attempts a type conversion. If it fails, I want to try something else, and if that also fails, then rethrow the original exception attempted by the first conversion. The problem is that the only way I know of to rethrow is to have 'throw;' sitting at the end of the catch block. What happens when I only want the rethrow to happen from within another catch block?
try
{
valueFromData = Convert.ChangeType(valueFromData, pi.PropertyType);
}
catch(InvalidCastException e)
{
Debug.WriteLine(String.Concat("Info - Direct conversion failed. Attempting to convert using String as an intermidiate type."));
try { valueFromData = Convert.ChangeType(valueFromData.ToString(), pi.PropertyType); }
catch { throw e; }
}
As you can see above, I have to use 'throw e;', which resets the call stack.
Only workaround I've though of so far is (imo) gross:
bool handled = true;
...
catch { handled = false; }
if( !handled ) throw;
There is no way to rethrow an exception from an outer catch block inside an inner catch block. The best way to achieve this pattern is to note whether or not the inner operation succeeded
catch (InvalidCastException e) {
bool threw = false;
try {
...
} catch {
threw = true;
}
if (threw) {
throw;
}
}
If you are intending to make multiple attempts at conversion then it certainly makes sense to use non-throwing operations where applicable so that you sidestep the problem entirely.
Supposing that's not possible for the sake of argument, the next step is to question the throw e; approach. In the example code you give, IMHO there is no problem at all if your throw resets the call stack. Once someone gets to the source code for this method (which the modified call stack would still point to), I think it's pretty obvious what's going on. So while resetting the call stack is always a questionable decision, in this particular case it should be allowed to happen because there would be no tangible drawback.
Finally, the workaround you mention is interesting as well as gross (agree on that!).
I tried the following and it seems to achieve your goal, when the 2nd exception occurs (in this case, the ArgumentException) it throws the first exception (InvalidCastException)
[TestMethod]
[ExpectedException(typeof(InvalidCastException))]
public void ReThrowException() {
var ret = false;
try {
ret = F1(1);
}
catch (InvalidCastException ex) {
try {
ret = F1(2);
}
catch (Exception e) {
Debug.WriteLine(e.Message);
throw ex;
}
}
}
private bool F1(int i) {
if (i == 1) {
throw new InvalidCastException();
} else {
throw new ArgumentException();
}
return false;
}
Hope this helps,
Alan.

Where should I catch exceptions when making use of '"using" keyword in the code?

Which one is better in structure?
class Program
{
static void Main(string[] args)
{
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
or...
class Program
{
static void Main(string[] args)
{
using (Foo f = new Foo())
{
try
{
//some commands that potentially produce exceptions.
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Either is fine, depending on what you are going to do in the catch. If you need to use f in your catch then it needs to be within the using statement. However in your example there is no difference.
EDIT:
As pointed out elsewhere it also depends on whether you are trying to catch just exceptions generated in the block following the using or including the object creation in the using statement. If it is in the block following the using then it is as I described. If you want to catch exceptions generated by Foo f = new Foo() then you need to use the first method.
I don't think it matters much, performance-wise. There is a slight difference though; in the second example, f is still available inside the exception handler, while in the first, it has gone out of scope. Conversely, in the first example, exceptions in the Foo constructor as well as its Dispose method will be caught, while in the second, they won't.
Either may or may not be what you want.
Check this post to understand better : http://www.ruchitsurati.net/index.php/2010/07/28/understanding-%E2%80%98using%E2%80%99-block-in-c/
Also read answers of this question : Catching exceptions thrown in the constructor of the target object of a Using block
the first one is bettwer one
class Program
{
static void Main(string[] args)
{
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
because if you see the IL code of this try and catch block not wrap the inialization of the object.
The first is better, because it will catch any exceptions thrown during the dispose process. Of course, you shouldn't throw any exceptions when disposing, but stuff happens.
First one is the better one .if any exception comes it will catch.
try
{
using (Foo f = new Foo())
{
//some commands that potentially produce exceptions.
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
The concept of using is it will dispose the object created in the using.i.e it automatically calls the IDispose method.Based on the requirement use the using.
Using is just
Foo f = null;
try
{
f = new Foo();
}
finally
{
if (f is IDisposable)
f.Dispose();
}
Seeing that you can achive catching exceptions like this:
Foo f = null;
try
{
f = new Foo();
}
catch (Exception ex)
{
// handle exception
}
finally
{
if (f is IDisposable)
f.Dispose();
}

Ignore a Specific Typed Exception

I would like to ignore a specific Type of exception in a group of statements; without having to put empty Try..Catches around them.
try{ o1.Update(); } catch (Exceptions.NoChangeMade ex) {}
try{ o2.Update(); } catch (Exceptions.NoChangeMade ex) {}
try{ o3.Update(); } catch (Exceptions.NoChangeMade ex) {}
I would like either a On Error Resume type way, or a Continue way within the catch
Here's a simple way:
ExecuteIgnore(o1.Update);
ExecuteIgnore(o2.Update);
ExecuteIgnore(o3.Update);
...
private static void ExecuteIgnore(Action action)
{
try { action(); }
catch(Exceptions.NoChangeMade) { }
}
You can make it even more generic (if a bit longer) like this:
ExecuteIgnore<Exceptions.NoChangeMade>(o1.Update);
ExecuteIgnore<Exceptions.NoChangeMade>(o2.Update);
ExecuteIgnore<Exceptions.NoChangeMade>(o3.Update);
...
public static void ExecuteIgnore<T>(Action action) where T : Exception
{
try { action(); }
catch(T) { }
}
If you want them all to update, you don't really have a choice without wrapping the exception.
You could do something like:
var list = List<objects_to_update> ();
list.Add(o1);
list.Add(o2);
etc.
list.ForEach(x=>
try{list.Update()}
catch{}
);
You'll still have to wrap them in an exception, but at least this way you're only writing it once.
Are these o1, o2, o3 objects related? Could you put them in a collection or an array?
If you do this, you could modify your code to use a loop to update the items and then you could have the empty catch block effectively pass control on to the next iteration of the loop.
Some pseudocode to illustrate:
foreach(DataTypeOfO o in CollectionOfOs)
{
try
{
o.Update();
}
catch(Exceptions.NoChangeMade ex)
{ }
}
If o1/o2/o3 are all the same class then put 1 try catch in the .Update() method to catch the specific exception that you are looking for. Or better yet, change the code so that it does not throw the exception at all.

Categories

Resources