2009-03-07 3 views
12

코드 자체에서 참조되지 않는 어셈블리를 무시하므로 컴파일러에 사용되지 않는 참조 makes no difference을 제거한다는 내용을 읽었습니다."사용하지 않는 참조 제거"의 목적은 무엇입니까

그러나 나는 그 때문에 믿기 어려워 보이는데, Removing unused references의 실제 목적은 무엇입니까? 생성 된 어셈블리 크기 나 그 밖의 영향을받지 않습니다. 또는 스마트 동작이 C# 컴파일러 (csc.exe)에만 국한되며 vbc.exe에 고유하지 않습니까?

이 기능을 사용할 수 없다면 왜 ReSharper 기능으로 제공합니까? Visual Studio 프로젝트 구성 대화 상자 내에서 제공되는 이유는 무엇입니까?

어디에서 이것이 유용할까요? 내가 생각할 수있는 유일한 활동은 배포 단계입니다. 참조 (used 또는 unused)는 여전히 설치 프로그램에 의해 복사됩니다. 그러나 GAC에있는 어셈블리 (예 : BCL 어셈블리)의 경우에는 문제가되지 않습니다.

답변

14

런타임시 CLR이 참조 된 모듈을로드하지 못하게합니다. 이렇게하면 시작 시간이 단축됩니다 (각 모듈을로드하는 데 시간이 걸리기 때문입니다). 모듈의 크기에 따라 시작 시간이 크게 줄어들 수 있습니다.

이 방법을 테스트하는 한 가지 방법은 테스트 WinForms 프로젝트를 만들고 사용되지 않은 어셈블리 (예 : System.Web)에 참조를 추가 한 다음 실행 파일 (예 : F5)을 실행하고 첨부하는 것입니다. 로드 된 모듈 (디버그 -> Windows -> 모듈)을 보면 참조 된 어셈블리가로드 된 것을 볼 수 있습니다.

생각해 보면 CLR이 종속성 (종속성은 참조를 추가하면 종속성으로 표시됨)이 실제로 사용되는지 여부를 결정하는 것은 CLR에서 매우 어려울 것입니다 ... 특히 일부 코드 경로의 실행을 미리 알 수 없습니다.

+1

CLR은 런타임시 컴파일러 최적화로 참조가 제거 된 모듈을 어떻게로드합니까? 내가 여기서 무엇을 놓치고 있니? – Dan

+0

@ 단 - 또한 왜이 답변에 다른 upvotes가 있는지 이해하지 못합니다. 다른 게시물에서 읽은 것에서 컴파일러가 어셈블리 참조를 사용하지 않으면 최종 출력에 넣지 않습니다. 참조 된 어셈블리는 JIT가 해당 메서드에 대한 첫 번째 호출시에만로드됩니다. 이 대답이 증명으로 가져온로드 된 모듈 창은 디버그 모드에 있기 때문에 모든 참조를 표시 할 수 있습니다. – BornToCode

+0

@BornToCode 또한, CLR이 의존성이 실제로 사용되는지 여부를 결정하는 것이 어렵다면, "사용되지 않은 참조 제거"는 어떻게 작동합니까? 참조가 사용되는지 여부를 결정하는 것은 간단합니다. 코드가 해당 어셈블리의 네임 스페이스에서 아무 것도 참조하지 않으면 사용되지 않습니다. – Dan

12

작은 소스 파일 외에도 사용하지 않는 코드 나 참조가없는 깨끗한 소스 파일을 만드는 것이 더 좋습니다.

+0

덕분에, 크리 소페,하지만 문제는/왜 더 나은 방법 ... 남아? – Cerebrus

+2

소스 파일이 비대화되지 않아 사용하지 않는 코드/가져 오기가 생겨서 읽고 이해하기가 더 쉽기 때문에 더 좋습니다. 또한, 나는 컴파일러가 할 일이 적고 컴파일이 조금 더 빠를 것이라고 생각한다. (나는 이것에 대해 100 % 확실하지 않고 이것은 컴파일러에 따라 다르다) –

8

Visual Studio 2008에는 사용되지 않는 사용 지시문을 제거하는 기능이 있습니다.

사용하지 않는 코드를 제거하면 코드가 깨끗해 지지만 충돌의 위험을 줄일 수 있습니다. 때로는 여러 어셈블리에 같은 이름의 클래스가 있습니다. 예를 들어 System.DrawingSystem.Web.UI.WebControls에 모두 Image 클래스가 있습니다. 두 네임 스페이스 모두에 대한 지시문을 사용하고 Image 클래스를 사용하기 시작하면 컴파일러는 사용할 클래스 중 하나를 알 수 없습니다.

+0

+1 : 충돌의 위험을 줄인다. – Sung

6

프로젝트를 빠르게 컴파일하는 것이 최적화되었습니다. 컴파일러가 절대 사용되지 않는 메타 데이터를로드하는 것을 방지합니다. 사소한 것이지만 하드 드라이브의 속도와 파일 시스템 캐시 상태에 따라 50 밀리 초 정도가 될 것입니다.

C# 컴파일러는 실제로 사용되는 어셈블리에 대해 컴파일 된 어셈블리의 메타 데이터에서 .assembly 참조를 방출하기에 충분히 똑똑합니다. 따라서 Ngen.exe를 실행할 때 사용하지 않는 어셈블리의 네이티브 이미지는 생성하지 않습니다. JIT 컴파일러는 영향을받지 않으며 IL을 변환하는 데 필요한 어셈블리 만로드합니다.

+0

NGENed 어셈블리가로드 될 때 참조 된 어셈블리가 모두 나중에로드된다는 것을 의미 하는가? 즉, 네이티브 어셈블리를 지연로드 할 수 없습니까? 적어도 그것은 내 응용 프로그램 (JITed 대 NGENed)의로드 된 어셈블리를 비교할 때 표시됩니다. – Yves