내 의견 here에 확장하면 BinaryReader
클래스가 Dispose 패턴을 올바르게 구현하지 못합니다. 리플렉터에서이 클래스에서 찾고
이
, 그것은 다음과 같습니다 (.NET 3.5) : 그것은 implementaiton 명시 적 인터페이스 개발자를 강제 IDisposable.Dispose()
함으로써
는
public class BinaryReader : IDisposable
{
public virtual void Close()
{
this.Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Stream stream = this.m_stream;
this.m_stream = null;
if (stream != null)
{
stream.Close();
}
}
this.m_stream = null;
this.m_buffer = null;
this.m_decoder = null;
this.m_charBytes = null;
this.m_singleChar = null;
this.m_charBuffer = null;
}
void IDisposable.Dispose()
{
this.Dispose(true);
}
}
문제는 여기에 대신 Close()
를 호출하는 것입니다 Dispose()
.
이 문맥에서는 불균형 의미론의 경우가 있습니다. 판독기를 "열기"위한 호출이 없었기 때문에 독자를 "닫기"는 직관적이지 않았습니다.
Dispose()를 호출하기 위해 한 걸음 더 나아가려면 평소에 수행해야하는 작업이 아닌 IDisposable
으로 명시 적으로 캐스트해야합니다. Dispose(bool)
을 직접 호출 할 수있는 옵션이 있지만 부울 매개 변수가 무엇인지 어떻게 알 수 있습니까?
public class BinaryReader : IDisposable
{
public virtual void Close()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
Stream stream = this.m_stream;
this.m_stream = null;
if (stream != null)
{
stream.Close();
}
}
this.m_stream = null;
this.m_buffer = null;
this.m_decoder = null;
this.m_charBytes = null;
this.m_singleChar = null;
this.m_charBuffer = null;
}
public void Dispose()
{
this.Close();
}
}
이 당신이있는 경우 중 하나를 호출 Dispose(true)
를 호출 결과 계속 Close()
또는 Dispose()
, 중 하나를 호출 할 수 것입니다 :
제대로 패턴을 따라하기 위해서는으로 implmented되어 있어야합니다. (Close()
또는 ((IDisposable)reader).Dispose()
을 호출하여 실제 구현과 동일한 흐름입니다.
다행스럽게도 (또는 불행하게도, 당신이 그것을보고 선택하는 방법에 따라) BinaryReader
그것이 using 문에 허용되는 IDisposable
인터페이스 구현 않기 때문에 : 사실
using (BinaryReader reader = new BinaryReader(...))
{
}
표준 Dispose 패턴에서 벗어나지 않아야하는 완벽한 예입니다. –
또는 동일한 작업을 수행하는 BinaryReader.Close()를 호출하십시오. –
그렇다고하더라도 Close() 메서드를 구현하면 Dispose() 및 Dispose()에서 수행 한 작업이 Close()를 호출해야합니다. BinaryReader는 패턴을 제대로 따르지 않았습니다. –