질문 : Java / C #에서 RAII를 구현할 수없는 이유는 무엇입니까?
설명 : 가비지 수집기가 결정적이지 않다는 것을 알고 있습니다. 따라서 현재 언어 기능을 사용하면 범위 종료시 객체의 Dispose () 메서드를 자동으로 호출 할 수 없습니다. 그러나 그러한 결정적 기능을 추가 할 수 있습니까?
내 이해 :
RAII 구현은 두 가지 요구 사항을 충족해야한다고 생각합니다.
1. 리소스 수명은 범위에 속해야합니다.
2. 암시 적. 프로그래머가 명시 적으로 진술하지 않고 자원을 확보해야합니다. 명시 적 진술없이 메모리를 비우는 가비지 수집기와 유사합니다. "내 재성"은 클래스 사용 시점에서만 발생하면됩니다. 클래스 라이브러리 생성자는 물론 소멸자 또는 Dispose () 메서드를 명시 적으로 구현해야합니다.
Java / C #은 포인트 1을 만족합니다. C #에서 IDisposable을 구현하는 리소스는 "사용"범위에 바인딩 될 수 있습니다.
void test()
{
using(Resource r = new Resource())
{
r.foo();
}//resource released on scope exit
}
이것은 포인트 2를 만족시키지 않습니다. 프로그래머는 명시 적으로 개체를 특수한 "사용"범위에 묶어야합니다. 프로그래머는 명시 적으로 리소스를 스코프에 연결하여 누출을 생성하는 것을 잊어 버릴 수 있습니다.
실제로 "using"블록은 컴파일러에 의해 try-finally-dispose () 코드로 변환됩니다. try-finally-dispose () 패턴의 명시 적 특성과 동일합니다. 암시 적 방출이 없으면 범위에 대한 후크는 구문 설탕입니다.
void test()
{
//Programmer forgot (or was not aware of the need) to explicitly
//bind Resource to a scope.
Resource r = new Resource();
r.foo();
}//resource leaked!!!
스마트 포인터를 통해 스택에 후크되는 특수 객체를 허용하는 Java / C #에서 언어 기능을 만드는 것이 좋습니다. 이 기능을 사용하면 클래스를 스코프 바운드로 플래그 지정할 수 있으므로 항상 스택에 대한 후크로 생성됩니다. 다른 유형의 스마트 포인터에 대한 옵션이있을 수 있습니다.
class Resource - ScopeBound
{
/* class details */
void Dispose()
{
//free resource
}
}
void test()
{
//class Resource was flagged as ScopeBound so the tie to the stack is implicit.
Resource r = new Resource(); //r is a smart-pointer
r.foo();
}//resource released on scope exit.
내포가 "가치"라고 생각합니다. 가비지 수집의 암시가 "가치있는"것처럼. 명시 적 사용 블록은 눈에 상쾌하지만 try-finally-dispose ()에 비해 의미 론적 이점을 제공하지 않습니다.
그러한 기능을 Java / C # 언어로 구현하는 것은 실용적이지 않습니까? 오래된 코드를 손상시키지 않고 소개 할 수 있습니까?
using
의 실행 Dispose
됩니다 보장 (예외없이 죽어 갑자기 과정을 할인, 잘하는 모든 정리가 아마도 논쟁이되는 포인트, 슬로우).
struct
Dispose
S가되어 지금 에 관계없이 트리거하는 방법, 실행합니다. 범위 끝에 암시 적 파괴를 추가해도 도움이되지 않습니다.