The return statement terminates the execution of the method in which it appears and returns control to the calling method. When the method is executed and returns a value, we can imagine that C# puts this value where the method has been called. The returned value can be used for any purpose from the calling method.
There is no 'special' way of returning IDisposable. Show activity on this post. The return value simply has to implement IDisposable .
As several others have pointed out in general this is not a problem.
The only case it will cause you issues is if you return in the middle of a using statement and additionally return the in using variable. But then again, this would also cause you issues even if you didn't return and simply kept a reference to a variable.
using ( var x = new Something() ) {
// not a good idea
return x;
}
Just as bad
Something y;
using ( var x = new Something() ) {
y = x;
}
It's perfectly fine.
You are apparently thinking that
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
is blindly translated into:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
Which, admittedly, would be a problem, and would make the using
statement rather pointless --- which is why that's not what it does.
The compiler makes sure that the object is disposed before control leaves the block -- regardless of how it leaves the block.
It's absolutely fine - no problem at all. Why do you believe it's wrong?
A using statement is just syntactic sugar for a try/finally block, and as Grzenio says it's fine to return from a try block too.
The return expression will be evaluated, then the finally block will be executed, then the method will return.
This will work perfectly fine, just as returning in the middle of try{}finally{}
That is totally acceptable. A using statement ensures the IDisposable object will be disposed no matter what.
From MSDN:
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.
The code bellow shows how using
is working:
private class TestClass : IDisposable
{
private readonly string id;
public TestClass(string id)
{
Console.WriteLine("'{0}' is created.", id);
this.id = id;
}
public void Dispose()
{
Console.WriteLine("'{0}' is disposed.", id);
}
public override string ToString()
{
return id;
}
}
private static TestClass TestUsingClose()
{
using (var t1 = new TestClass("t1"))
{
using (var t2 = new TestClass("t2"))
{
using (var t3 = new TestClass("t3"))
{
return new TestClass(String.Format("Created from {0}, {1}, {2}", t1, t2, t3));
}
}
}
}
[TestMethod]
public void Test()
{
Assert.AreEqual("Created from t1, t2, t3", TestUsingClose().ToString());
}
Output:
't1' is created.
't2' is created.
't3' is created.
'Created from t1, t2, t3' is created.
't3' is disposed.
't2' is disposed.
't1' is disposed.
The disposed are called after the return statement but before the exit of the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With