programing

문 사용 vs.일회용.폐기()

goodsources 2023. 5. 21. 11:23
반응형

문 사용 vs.일회용.폐기()

.NET의 문장이 다음을 부르는 것으로 알고 있습니다.IDisposable물의Dispose()메서드는 코드가 블록을 빠져나오면 됩니다.

까?▁the▁does?using진술서는 다른 것을 합니까?그렇지 않으면 다음 두 코드 샘플이 정확히 동일한 결과를 얻는 것처럼 보일 것입니다.

Using Con as New Connection()
    Con.Open()
    'do whatever '
End Using

Dim Con as New Connection()
Con.Open()
'do whatever '
Con.Dispose()

제가 옳다는 것을 확인하거나 제가 틀렸다는 것을 지적하고 그 이유를 설명하는 사람에게 최선의 답변을 드리겠습니다.특정 계층은 다른 일을 할 수 있다는 것을 알고 있다는 것을 명심하세요.Dispose()방법들.이 질문은 그것의 여부에 관한 것입니다.using문은 객체를 호출하는 것과 정확히 같은 결과를 달성합니다.Dispose()방법.

using으로 다음과

try
{
  // code
}
finally
{
  obj.Dispose();
}

그래서 그것은 또한 전화하는 것의 이점이 있습니다.Dispose()처리되지 않은 예외가 블록 내의 코드에 던져진 경우에도 마찬가지입니다.

Brian Warshaw가 여기언급한 것처럼 그것은 단순히 구현입니다.try그리고.finally개체가 삭제되었는지 확인하기 위해 차단합니다.대답에 , 그의대답덧붙여에,여,using또한 block은 스코프사용하여 내부로 돌아가더라도 객체가 배치되도록 합니다.

한 번은 저 자신도 이것에 대해 궁금했고 다음과 같은 접근 방식을 사용하여 테스트했습니다.

사용자 지정 ID 일회용 테스트 클래스 및 기본

private class DisposableTest : IDisposable
{
    public string Name { get; set; }

    public void Dispose() { Console.WriteLine("{0}.Dispose() is called !", Name); }
}

public static void Main(string[] args)
{
    try
    {
        UsingReturnTest();
        UsingExceptionTest();                
    }
    catch { }

    try
    {
        DisposeReturnTest();
        DisposeExceptionTest();                
    }
    catch { }

    DisposeExtraTest();

    Console.ReadLine();
}        

테스트 사례 구현

private static string UsingReturnTest()
{
    using (DisposableTest usingReturn = new DisposableTest() { Name = "UsingReturn" })
    {
        return usingReturn.Name;
    }
}

private static void UsingExceptionTest()
{
    using (DisposableTest usingException = new DisposableTest() { Name = "UsingException" })
    {
        int x = int.Parse("NaN");
    }
}

private static string DisposeReturnTest()
{        
    DisposableTest disposeReturn = new DisposableTest() { Name = "DisposeReturn" };
    return disposeReturn.Name;
    disposeReturn.Dispose(); // # IDE Warning; Unreachable code detected
}

private static void DisposeExceptionTest()
{
    DisposableTest disposeException = new DisposableTest() { Name = "DisposeException" };
    int x = int.Parse("NaN");
    disposeException.Dispose();
}

private static void DisposeExtraTest()
{
    DisposableTest disposeExtra = null;
    try
    {
        disposeExtra = new DisposableTest() { Name = "DisposeExtra" };
        return;
    }
    catch { }
    finally
    {
        if (disposeExtra != null) { disposeExtra.Dispose(); }
    }
}

출력은 다음과 같습니다.

  • 반환 사용.Dispose()를 호출합니다!
  • 예외 사용.Dispose()를 호출합니다!
  • 여분을 처분합니다.Dispose()를 호출합니다!
//preceeding code
using (con = new Connection()) {
    con.Open()
    //do whatever
}
//following code

는 다음과 같습니다(con에 대한 제한된 범위 참고).

//preceeding code
{
    var con = new Connection();
    try {
        con.Open()
        //do whatever
    } finally {
        if (con != null) con.Dispose();
    }
}
//following code

이에 대한 설명은 다음과 같습니다. http://msdn.microsoft.com/en-us/library/yh598w02.aspx

명령문을 사용하면 개체에서 메서드를 호출하는 동안 예외가 발생하더라도 Dispose가 호출됩니다.객체를 시도 블록 안에 넣은 다음 최종 블록에서 Dispose를 호출하면 동일한 결과를 얻을있습니다. 실제로 이것이 컴파일러가 사용 문을 변환하는 방법입니다.

A using보다 더 명확하고 간결합니다.try...finally{Dispose()}구성, 그리고 블록이 다음과 같이 나가는 것을 허용하지 않는 거의 모든 경우에 사용되어야 합니다.Dispose불리어지는"수동" 폐기가 더 나은 일반적인 상황은 다음과 같습니다.

  1. ID Disposable을 구현할 수도 있고 구현하지 않을 수도 있는 것을 반환하는 팩토리 메서드를 호출하는 메서드가 있지만, 구현할 경우 Disposured여야 합니다(일반적이지 않은 IEnumberable에서 발생하는 시나리오).Enumerator()'를 가져옵니다.잘 설계된 공장 인터페이스는 "ID Disposable"을 구현하는 유형(일반적으로 "IE numerator"의 경우처럼 아무 것도 구현하지 않는 유형)을 반환하거나 그렇지 않으면 호출자가 반환된 개체를 "Disposure"할 것으로 예상되지 않음을 지정해야 합니다.안타깝게도 일반적이지 않은 "IEnumberable"과 같은 일부 인터페이스는 두 가지 기준을 모두 충족하지 못합니다.이러한 경우에는 선언된 유형이 "IDisposable"을 구현하는 저장 위치에서만 작동하기 때문에 "use"를 잘 사용할 수 없습니다.
  2. "ID Disposable" 객체는 블록이 종료된 후에도 유지될 것으로 예상됩니다("ID Disposable" 필드를 설정하거나 공장 방식에서 "ID Disposable"을 반환할 때 자주 발생합니다).

반품할 때는IDisposable공장 방식에서 다음과 같은 것을 사용해야 합니다.

bookmook = false;일회용 클래스 mything;해라{My Thing = 새로운 일회용 클래스();...ok = true;내 물건을 돌려줍니다.}마침내.{if (!ok){if (myThing!= null)나의 것폐기();}}

을 확실히 하기 위해myThing얻을 것입니다Disposed 만약 그것이 반환되지 않는다면.고용할 수 있는 방법이 있으면 좋겠습니다.using일부 "폐기 취소" 방법과 함께, 그러나 그러한 방법은 존재하지 않습니다.

둘 사이의 차이점은 예외가 발생할 경우

Con.Open()
'do whatever

Con.Dispose호출되지 않습니다.

나는 VB 구문에 대해 잘 모르지만, C#에서 동등한 코드는

try
{
    con = new Connection();
    // Do whatever
}
finally
{
    if (con != null) con.Dispose();
}

사용 블록은 다음을 보장합니다.Dispose()예외가 발생한 경우 호출됩니다.

두 번째 샘플은 그렇게 하지 않습니다.

한다면Con.Open()예외를 던졌습니다, 첫 번째 경우에 당신은 그것을 보장합니다.Con.Dispose()이 호출됩니다.두 번째 경우, 예외는 위로 전파되고,Con.Dispose()호출되지 않습니다.

using문은 예외가 발생한 경우 개체가 삭제되도록 보장합니다.이것은 폐기를 호출하는 것과 같습니다.finally블록으로 막다

닫힌 블록을 사용하여 시도/최종적으로 랩핑하여 최종 블록에서 Dispose를 호출합니다.이렇게 하면 예외가 발생하더라도 Dispose가 호출됩니다.

안전상의 이유로 거의 모든 경우에 사용해야 합니다.

메모리가 작동하는 경우, 사용은 객체를 둘러싼 코드 블록이 어떻게 빠져나오는지에 관계없이 객체가 폐기된다는 것을 보장합니다.한 번에 블록을 둘러싸면 이렇게 됩니다.마지막으로 차단하고 사용된 변수의 null 여부를 확인한 다음 null이 아닌 경우 삭제합니다.예외가 발생한 경우 스택에 거품이 발생할 수 있습니다.그것을 제외하고, 그것이 하는 모든 것은 null이 아닌 일회용 물체의 폐기를 보장하는 것입니다.

try
{
  var myDisposable = new DisposableObject();
  myDisposable.DoSomething();
}
finally
{
  if (myDisposable != null)
    ((IDisposable)myDisposable).Dispose();
}

언급URL : https://stackoverflow.com/questions/10984336/using-statement-vs-idisposable-dispose

반응형