Как обработать доступные объекты, на которые у нас нет ссылки?

Существуют несколько (очень немного) случаи, где может быть необходимо выполнить определенное действие, когда чистый управляемый объект больше не используется, я не могу придумать пример первое, что пришло на ум, но я видел несколько законного использования за эти годы. Но главная причина состоит в том, чтобы очистить любые неуправляемые ресурсы, которые мог бы использовать объект.

Так, в целом, Вы не должны будете использовать Расположить/Завершить шаблон, если Вы не будете использовать неуправляемые ресурсы.

7
задан SLaks 8 October 2009 в 18:26
поделиться

4 ответа

Задача метода CreatePenFromColor - удалить экземпляр Brush. На первый взгляд это не очевидно, но если вы углубитесь в реализацию класса Pen, вы увидите, что он не удерживает переданный в Brush экземпляр. Вместо этого он просто использует его для вычисления нескольких значений. Таким образом, у экземпляра Brush нет причин жить дальше вызова CreatePenFromColor, и метод должен удалять экземпляр.

9
ответ дан 6 December 2019 в 10:51
поделиться

Вы все равно должны избавиться от него, когда закончите.

Например, вы могли бы назвать это так:

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

Если метод возвращает объект IDisposable, вы обязаны его удалить.

[Edit] Теперь у меня возник вопрос - вы используете конструктор Pen (Brush b).

a. В этом случае кажется, что Pen не нуждается в экземпляре Brush после конструктора, поэтому ваш метод может выглядеть следующим образом:

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

b. Почему бы просто не использовать Pen (Цветной цвет) ?

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

c. (относительно комментария) Если Pen будет содержать внутреннюю ссылку на Brush, вы не сможете избавиться от нее, пока не закончите с Pen. В этом случае я бы выбрал класс, который будет выполнять эту работу за меня:

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();
     }
}

, а затем использовать его следующим образом:

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

Отказ от ответственности: IDisposable реализован не в соответствии с рекомендациями, а только для демонстрации. Кроме того, весь пример используется только для того, чтобы показать, как инкапсулировать ссылку при необходимости. Конечно, вам следует выбрать Pen (цвет).

6
ответ дан 6 December 2019 в 10:51
поделиться

У вашей проблемы нет общего решения.

В вашем конкретном примере это не проблема, потому что у Pen есть конструктор, который принимает цвет напрямую.

Некоторые классы будут располагать свой конструктор сами параметры (особенно классы, относящиеся к Stream); проверьте каждый класс в Reflector.

Если класс, который вы возвращаете, наследуется от Component, вы можете добавить обработчик к его событию Disposed.

Если возвращаемый класс не запечатан, вы можете создать унаследованный версия, которая также удаляет объект, из которого вы его создали.

Наконец, если вы действительно этого хотите, вы можете создать класс-оболочку, который содержит объект, который вы возвращаете, и избавляет от параметра конструктора. Однако это было бы очень запутанным, и я бы не рекомендовал это.

2
ответ дан 6 December 2019 в 10:51
поделиться

Когда метод передает экземпляр IDisposable, он одновременно передает ответственность за управление сроком службы.

Теперь ответственность за удаление объекта после использования лежит на вызывающей стороне. Если этот объект содержит другие объекты IDisposable, по соглашению мы должны ожидать, что контейнер правильно избавится от своих дочерних элементов, когда мы его удаляем - в противном случае это означало бы ошибку в контейнере.

В вашем конкретном примере вы должны ожидать, что Pen будет утилизируйте его внутренний экземпляр Brush при его утилизации.

0
ответ дан 6 December 2019 в 10:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: