2010-12-10 4 views
13

정적 클래스에서 공개 상수의 값을 변경 한 다음 어셈블리의 이전 복사본을 새로 컴파일 된 버전으로 바꾼 경우 약간 놀랍습니다. 놀랍게도 어셈블리를 참조한 기존 프로그램이 상수의 새로운 값을 선택하지 못했습니다. 즉, 실행 파일을 다시 컴파일하지 않고 대신 해당 어셈블리를 교체했습니다..NET에서 왜 JIT 시간이 아닌 컴파일 타임에 상수가 계산됩니까?

내 실험에 대한 자세한 설명은 내가이 동작에 의해 매우 놀랄로 인정한다 How constant is a constant?

이다. 무슨 일이 벌어지는 지 이해하지만 이해가 안됩니다 이유는입니다. 컴파일 타임이 아닌 JIT 시간에 상수를 선택할 수없는 특별한 기술적 인 이유가 있습니까? 그 일을하는 것이 일을 망칠 수있는 경우가 있습니까?

+0

이 너무 많은 책, 블로그 게시물에서 논의 된 행동이다, 그래서 –

+0

@Lex : 사실 그 놀라운 일이 아니다 :

내가 이렇게 내 고정 소수점 형식이 사용 이상하게, I 이전에 토론을 한 번도 해보지 않았습니다. 나는 아직도 왜 그런지 궁금해. –

+1

나는 아직도 그것을 사용하는 어셈블리로 굽는 이점이 무엇인지 모르겠다. – CodesInChaos

답변

30

상수는 상수입니다. 전체 시간은 입니다.. 상수는 pi의 값, 또는 선두 원자의 양성자 수 같은 것들입니다.

상수가 변경되면 은 실제로 상수가 아닙니다.; 대신 읽기 전용 필드를 사용하십시오.

또한 프레임 워크 디자인 가이드 라인을 참조하는 상태 : 변경하지 않습니다 상수에 대한

를 사용하여 일정 필드. 컴파일러는 const 필드의 값을 호출 코드에 직접 굽습니다. 따라서 호환성을 손상시킬 위험없이 const 값을 변경할 수 없습니다.

본질적으로 정수에 의존하는 모든 것을 다시 컴파일하지 않고 상수를 변경하면 메서드의 서명을 변경하는 것만 큼 모든 비트가 달라집니다. 컴파일러는 종속 어셈블리를 컴파일 할 때 참조 된 어셈블리의 메타 데이터에 대한 모든 종류의 가정에 "가정합니다". 으로 변경하면 작업을 계속 유지할 수 있습니다.

+0

JIT 컴파일러는 읽기 전용 필드를 평가 한 다음 원시 코드로 컴파일 할 때이를 상수로 처리합니까? 즉, 상수 사용과 읽기 전용 필드 사용간에 성능 차이가 있습니까? –

+5

@ 짐 : 잘 모르겠습니다.첫째, 훌륭한 JIT 컴파일러가 6 개 이상 있고 그 중 어느 것도 전문가가 아닙니다. 둘째, JIT 컴파일러는 디버거가 연결되었는지 여부와 같이 런타임에 발생하는 작업을 기반으로 동작을 변경하는 경우가 많습니다. 셋째, 성능에 대해 염려하는 경우 두 가지 방법으로 코드를 작성하고 실행하고 차이를 측정 할 수 있는지 확인하십시오. 그 차이가 너무 작아 측정 할 수 없다면 처음에는 걱정해야 할 차이가 없을 것입니다. –

+7

PI가 이제 정확히 3이라고 들었습니다. – ChaosPandion

1

"상수"를 선언하는 세 번째 방법은 public static 속성입니다.

public static string ConstString {get{return "First test";}} 

이것은 읽기 전용 필드의 버전 의미를 가지고 있지만, 지터 게터를 인라인 경우에는 JIT 시간 일정해진다. 그리고 const과 달리 사용자 정의 유형에 사용할 수 있습니다.

각 속성 액세스에 새 인스턴스를 할당하지 않으려 고하므로 value-types 및 string에는 정적 속성을 사용하는 것이 좋지만 사용자 정의 클래스에는 사용하지 않는 것이 좋습니다.

public struct FixedPoint 
{ 
    private int raw; 
    private const fracDigits=16; 

    private FixedPoint(int raw) 
    { 
    this.raw=raw; 
    } 

    public static FixedPoint Zero{get{return new FixedPoint();}} 
    public static FixedPoint One{get{return new FixedPoint(1<<fracDigits);}} 
    public static FixedPoint MaxValue{get{return new FixedPoint(int.MaxValue);}} 
} 
관련 문제