If I use object initializers in using-block I get Code Analysis warning about not disposing the object properly:
CA2000 : Microsoft.Reliability : In method 'ReCaptcha.CreateReCaptcha(this HtmlHelper, string, string)', object '<>g__initLocal0' is not disposed along all exception paths. Call System.IDisposable.Dispose on object '<>g__initLocal0' before all references to it are out of scope.
Here is the code:
using (var control = new ReCaptchaControl()
{
ID = id,
Theme = theme,
SkipRecaptcha = false
})
{
// Do something here
}
If I do not use object initializers, Code Analysis is happy:
using (var control = new ReCaptchaControl())
{
control.ID = id;
control.Theme = theme;
control.SkipRecaptcha = false;
// Do something here
}
What is the difference between those two code blocks? I thought that they would result in same IL. Or is this a bug in the code analysis engine?
No, there's a difference.
An object initializer only assigns to the variable after all the properties have been set. In other words, this:
Foo x = new Foo { Bar = "Baz" };
is equivalent to:
Foo tmp = new Foo();
tmp.Bar = "Baz";
Foo x = tmp;
That means that if one of the property setters threw an exception in your case, the object wouldn't be disposed.
EDIT: As I thought... try this:
using System;
public class ThrowingDisposable : IDisposable
{
public string Name { get; set; }
public string Bang { set { throw new Exception(); } }
public ThrowingDisposable()
{
Console.WriteLine("Creating");
}
public void Dispose()
{
Console.WriteLine("Disposing {0}", Name);
}
}
class Test
{
static void Main()
{
PropertiesInUsingBlock();
WithObjectInitializer();
}
static void PropertiesInUsingBlock()
{
try
{
using (var x = new ThrowingDisposable())
{
x.Name = "In using block";
x.Bang = "Ouch";
}
}
catch (Exception)
{
Console.WriteLine("Caught exception");
}
}
static void WithObjectInitializer()
{
try
{
using (var x = new ThrowingDisposable
{
Name = "Object initializer",
Bang = "Ouch"
})
{
// Nothing
}
}
catch (Exception)
{
Console.WriteLine("Caught exception");
}
}
}
Output:
Creating
Disposing In using block
Caught exception
Creating
Caught exception
Note how there's no "Disposing Object initializer" line.
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