The normal pattern for avoiding the CA2000 warning about non-disposed locals is to use a temp variable that gets disposed if anything goes wrong, like:
Foo f = null;
try
{
f = new Foo();
Foo result = f;
f = null;
return result;
}
finally
{
if (f != null)
{
f.Dispose();
}
}
A bit verbose, but it works, and it makes sense. But how does one apply that pattern to chained constructors, like this:
public HomeController ( IDataRepository db )
{
this.repo = db ?? new SqlDataRepository();
}
public HomeController ( )
: this(new SqlDataRepository())
{
}
This code is throwing up two CA2000 warnings, one per constructor. The first one I can get rid of using the temp variable pattern. It's pretty annoying, since there doesn't see to be any way for the local to go out of scope after it's constructed but before it gets assigned to the member field, which gets cleaned up later. So I dunno what CA's problem is, but at least I know what to do to fix it.
But, as far as I can figure out, there isn't any alternative way to write the second constructor call to introduce a try/finally. The field being assigned to is read-only, so it must be set in a constructor. And C# won't let you call chained constructors anywhere but immediately before the constructor body. And, of the two, the second warning is actually the more legitimate one -- the call to the chained constructor could (in theory, if it did any actual work) throw an exception and leave the newly constructed parameter undisposed.
Of course, I can always just suppress this message (which CA2000 seems to need a lot of), but if there's an actual way to eliminate the problem I'd prefer to do that.