использование 'using' в .NET - PullRequest
       35

использование 'using' в .NET

5 голосов
/ 13 января 2010

В приведенном ниже примере, будут ли возвращенные pen уничтожены (уничтожены) или нет?

' VB'
Public Function GetPen() As System.Drawing.Pen
  Using pen As New System.Drawing.Pen(_Color, _Width)
    pen.DashStyle = _DashStyle
    Return pen
  End Using
End Function

// C#
public System.Drawing.Pen GetPen()
{
    using (System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width)) 
    {
        pen.DashStyle = _DashStyle;
        return pen;
    }
}

[EDIT]

Еще одна точность... Объект Pen отправляется вызывающей стороне GetPen по ссылке или «клонируется» как структура?Я знаю, это класс, но с объектами GDI я никогда не уверен ...

Будет ли он уничтожен (уничтожен) pen, созданным в GetPen(), когда внешний метод избавится от его pen полученный с GetPen()?

Ответы [ 11 ]

7 голосов
/ 13 января 2010

Да, он будет утилизирован. Затем вы возвращаете его в удаленном состоянии, чтобы оно ни к чему не привело. Если вы хотите использовать фабричный метод, подобный этому, для возврата экземпляра Pen, вам придется самостоятельно утилизировать его внутри метода, а не использовать блок using в методе, подобном этому.

6 голосов
/ 13 января 2010

Перо не обязательно будет собирать мусор, но у него будет вызываться метод Dispose ().

3 голосов
/ 13 января 2010

Ручка будет утилизирована перед возвратом. Это эквивалент

public System.Drawing.Pen GetPen()
{
    try
    {
      System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width);

      pen.DashStyle = _DashStyle;
    }
    finally
    {
      pen.Dispose();
    }
    return pen;

}
3 голосов
/ 13 января 2010

Да, ручка будет утилизирована. Это действительно плохая идея; Вы возвращаете ручку, которая уже утилизирована!

Что вы хотите сделать, это удалить оператор Using из GetPen. Оператор Using должен использоваться вызывающими сторонами GetPen:

Using pen As Pen = GetPen()
    ''// Draw with this pen
End Using

Или в C #:

using(Pen pen = GetPen())
{
    // Draw with this pen
}

[EDIT]

Да, ссылка на вызывающий метод возвращается, а не копия. Вот почему, если вы используете перо в GetPen, вы не можете использовать это перо в вызывающем методе; -)

Поскольку GetPen и вызывающий метод указывают на один и тот же объект Pen, вам просто нужно вызвать Dispose в вызывающем методе.

1 голос
/ 13 января 2010

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

public System.Drawing.Pen GetPen() 
{ 
    System.Drawing.Pen pen = new System.Drawing.Pen(_Color, _Width)
    { 
        DashStyle = _DashStyle; 
    } 
    return pen; 
} 

Затем позвоните, используя:

using (System.Drawing.Pen pen = GetPen())
{
    //Do stuff with your pen...
}
1 голос
/ 13 января 2010

Да.

Возвращенный объект Pen будет уничтожен до того, как вызывающий его получит.

В методах стиля Get() вы не хотите иметь дело с удалением объектов. Разрешить вызывающей стороне избавиться от объекта ПОСЛЕ , что они сделали с ним. Я ожидаю, что вызывающая функция будет выглядеть следующим образом:

using(Pen myPen = GetPen())
{
    // My code here.
}
1 голос
/ 13 января 2010

Он будет автоматически утилизирован после возврата. Используя силы использование Dispose () имплицитно

1 голос
/ 13 января 2010

Да, он будет утилизирован.

0 голосов
/ 13 января 2010

использование равно примерно следующему утверждению:

попытка {

     var something = new something() ;

}

наконец {

 if (something != null)
 { something.Dispose();}   

}

0 голосов
/ 13 января 2010

Да. В версиях вашего кода на C # и VB.net метод .Dispose () вызывается перед возвратом функции. Это не то же самое, что уничтожить его (объект все еще существует), но для всех практических целей объект бесполезен, потому что теперь освобождается неуправляемый ресурс, который сделал его интересным и полезным.

Правильный шаблон для использования при создании ресурса IDisposable внутри функции - просто вернуть его и использовать объявление using для вызова функции, например:

public System.Drawing.Pen GetPen()
{
    var pen = new System.Drawing.Pen(_Color, _Width)) 
    pen.DashStyle = _DashStyle;
    return pen;
}

public void FunctionThatCallsGetPen()
{
    using (System.Drawing.Pen pen = GetPen())
    {
       //use pen here
    }
}
...