How are IDisposable objects passed to base constructor arguments handled in C # if initialization fails?

If I pass the IDisposable object to the constructor of the base class using the base(...) construct, I cause a stupid error in FxCop about freeing from IDisposable warning is sometimes useful in other places, so I don’t want to disable it, but I understand that it’s not I know the exact semantics that I should use.

The responsibility of the main constructor is to wrap its body in try / catch to make sure that the IDisposable object is properly disposed of in case of an exception?

Related questions:

+4
source share
4 answers

Not quite the answer to the question, but ...

You do not need to completely disable the rule - you can suppress it for methods in which you know that the analysis is overly zealous:

 [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Your reasons go here")] public YourClass(IDisposable obj) : base(obj) { } 

Even though the CA2000 analysis is so disrupted that it would be more useful to disable it altogether.

+4
source

Yes, neither the class constructor nor using the call Dispose statement in case of an exception in the constructor.

It is your task to handle exceptions in the constructor, because an object that has not yet been created cannot be "deleted" in the same way as a successfully created one.

This is not related to the base constructor, this is a big problem:

 class A: IDisposable { public A() // constructor { r1 = new Resource(res1_id); // resource aquisition r2 = new Resource(res2_id); // assume exception here } public void Dispose() { r1.Release(); // released successfully r2.Release(); // what to do? } Resource r1, r2; } 
+2
source

A simple rule: if you create * it, it is your responsibility to ensure that it is deleted. Conversely, if a method (whether it is a constructor or otherwise) does not create a one-time object, I would not expect it to destroy it. (* Creation includes calls to methods that return IDisposable.)

So something like

 public Foo(SomeDisposable obj) : base(obj) { } 

I expect to see something like

 using (SomeDisposable obj = new SomeDisposable()) { Foo foo = new Foo(obj); } 

And not

 Foo foo = new Foo(new SomeDisposable()); 

If you have a constructor without parameters for Foo , and you want to call the base constructor with a one-time object, you are in a much more complex position and probably where the rule is trying to protect you, I would say to avoid such a position, or encoding the base to create, and therefore be responsible for IDisposable, or have a 1: 1 mapping between constuctors and IDisposable parameters, so parameterless Foo does not call a parameterized base.

But there should not be a task of a method or constructor to guess that you ended up with the object in which you passed, because how should it know? You may have other options to use.

+1
source

I came up with a good sample, which I posted as an answer to my own related question here , which allows you to safely combine the declaration and initialization of iDisposable fields and make sure they are deleted even when the constructor fails. The code might clear a bit, but it seems to be here.

The only thing I can’t understand how to do this is to enable event tuning / cleaning. Having a list of objects that have been selected does not translate into a list of subscriptions to events that need to be unwound, even through reflection.

0
source

All Articles