How to handle disposable objects to which we have no links?

If you have a brush and pen, as in:

Brush b = new SolidBrush(color); Pen p = new Pen(b); 

and dispose of them like this:

 b.Dispose(); p.Dispose(); 

How would you order if it were:

Pen p = CreatePenFromColor(color) , which will create a brush and pen for you? I can’t destroy the brush inside this method, right?

This method can not be used with disposable objects?

EDIT: I mean, how do you handle the BRUSH?

+7
garbage-collection c # idisposable
source share
5 answers

The task of the CreatePenFromColor method is to get rid of the Brush instance. This is not obvious at first glance, but if you delve into the Pen class implementation, you will see that it is not held in the passed Brush instance. Instead, it simply uses it to compute multiple values. Therefore, there is no reason that the Brush instance will live outside the call to CreatePenFromColor, and the method should recycle the instance.

+9
source share

You still have to dispose of when you're done.

For example, you can call it like this:

 using (Pen p = CreatePenFromColor(color)) { // do something } 

If the method returns an IDisposable, your responsibility is to dispose of it.

[Edit] Now I have a question: are you using the Pen constructor (Brush b).

but. In this case, it seems that Pen doesn't need a Brush instance after the constructor, so your method might look like this:

 public Pen CreatePenFromColor(Color c) { using (Brush b = new SolidBrush(c)) { return new Pen(b); } } 

b. Why not just use a Pen (color) ?

 public Pen CreatePenFromColor(Color c) { return new Pen(c); } 

from. (relative to the comment) If the pen contains a link to the brush inside, then you cannot destroy it before you finish using Pen. In this case, I would go to a class that would do the job for me:

 public class PenHelper : IDisposable { private readonly Brush _brush; public PenHelper(Color color) { _brush = new SolidBrush(color); } public Pen CreatePen() { return new Pen(_brush); } public void Dispose() { _brush.Dispose(); } } 

and then use it like this:

 using (PenHelper penHelper = new PenHelper(Color.Black)) { using (Pen pen = penHelper.CreatePen()) { // do stuff } } 

Disclaimer: IDisposable is not implemented as recommended, but rather for demonstration purposes only. In addition, the entire example is used only to show how to encapsulate the link when necessary. Of course you have to go for Pen (color).

+6
source share

Your problem has no general solution.

In your specific example, this is not a problem, because Pen has a constructor that takes color directly.

Some classes themselves will determine the parameters of their constructor themselves (especially classes associated with the stream); check each class in Reflector.

If the returned class inherits from Component, you can add a handler to its Disposed event.

If the return class is not sealed, you can create an inherited version that also provides the object from which you created it.

Finally, if you really want to, you can create a wrapper class that contains the object you are returning and has a constructor parameter. However, that would be very confusing, and I would not recommend it.

+2
source share

One of my letters with many classes related to graphics is that there is no consistent pattern to solve such problems. What is really needed is a means of implementing partial reference counting. Not in the COM style, where link traversal requires constant rolling of reference samples, but in a means by which, given the IDisposable graphics object, you can request another instance that has the same base resource. The resources themselves will be encapsulated in a shared object with a reference count. Creating another instance of the link will increase the counter; calling Dispose on the reference instance will reduce it. This avoids 95% of the overhead of link counting while maintaining 99% of the benefits.

+1
source share

When a method disconnects an instance of IDisposable, it simultaneously transfers responsibility for managing the life cycle.

Now the caller is responsible for removing the item after use. If this object contains other IDisposable objects, by convention we should expect the container to properly dispose of its children when we destroy it, otherwise it would mean an error in the container.

In your specific example, you should expect Pen to delete its internal Brush instance when you place it.

0
source share

All Articles