[c#] 문 사용이 끝나기 전에 돌아 오면 어떻게 되나요? 처분이 호출됩니까?

다음 코드가 있습니다.

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

dispose()메서드는 using문 중괄호 끝에서 호출됩니다 }. 나는 이후 return의 끝나기 전에 using문, 의지 MemoryStream객체가 제대로 배치 할 수? 여기서 무슨 일이 일어나나요?



답변

네, Dispose부릅니다. using블록을 떠나는 데 걸린 수단에 관계없이 실행이 블록 범위를 벗어나는 즉시 호출됩니다 return.

@Noldorin 올바르게 사용하여 지적 하듯이 using코드 블록을 컴파일 도착 try/ finallyDispose에서 호출되는 finally블록. 예를 들어 다음 코드 :

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

효과적으로 :

MemoryStream ms = new MemoryStream();
try
{
    // code
    return 0;
}
finally
{
    ms.Dispose();
}

따라서 블록이 실행을 마친 finally후에 실행이 보장 되기 때문에 try실행 경로에 Dispose관계없이 무엇이든지 호출이 보장됩니다.

자세한 내용은 이 MSDN 문서를 참조하십시오 .

부록 : 추가
할 약간의주의 사항 : Dispose은 호출이 보장 되기 때문에 Dispose구현할 때 예외가 발생하지 않도록하는 것이 거의 항상 좋은 생각 IDisposable입니다. 불행하게도, 핵심 라이브러리의 일부 클래스가 어떻게 특정 상황에 던져 Dispose내가 당신을 찾고 있어요, WCF 서비스 참조 / 클라이언트 프록시 -라고는! -그리고 그럴 때 Dispose예외 스택 해제 중에 호출 된 경우 원래 예외를 추적하는 것이 매우 어려울 수 있습니다 . 원래 예외가 Dispose호출에 의해 생성 된 새 예외에 찬성하여 삼키기 때문입니다 . 그것은 미친 듯이 실망 스러울 수 있습니다. 아니면 그게 실망 스럽습니까? 둘 중 하나. 둘 다.


답변

using문은 try ... finally블록 과 똑같이 동작 하므로 항상 모든 코드 종료 경로에서 실행됩니다. 그러나 나는 그들이 finally블록이 호출되지 않는 매우 드문 상황에 처해 있다고 믿습니다 . 내가 기억할 수있는 한 가지 예는 백그라운드 스레드가 활성화 된 동안 포 그라운드 스레드가 종료되는 경우입니다. GC를 제외한 모든 스레드가 일시 중지되어 finally블록이 실행되지 않습니다.

명백한 편집 : IDisposable 개체를 처리 할 수있는 논리를 제외하고는 동일하게 동작합니다.

보너스 내용 : 스택 가능 (유형이 다른 경우) :

using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{

}

또한 쉼표로 구분 (유형이 동일한 경우) :

using (SqlCommand comm = new SqlCommand("", conn),
       SqlCommand comm2 = new SqlCommand("", conn))
{

}


답변

MemoryStream 객체는 적절하게 삭제되므로 걱정할 필요가 없습니다.


답변


답변

컴파일 한 후 리플렉터에서 코드를 살펴보십시오. 컴파일러가 코드를 리팩토링하여 dispose가 스트림에서 호출되도록합니다.


답변