beforefieldinit 플래그는 무엇을합니까?


82

beforefieldinit 플래그는 무엇을합니까? 내 클래스의 IL을 살펴보면이 플래그가 표시되지만이 플래그가 실제로 무엇을하는지 모르겠습니다.

답변:


132

이 문제에 대한 내 기사 를 참조하십시오 .

기본적으로 beforefieldinit"정적 필드가 참조되기 전에 언제든지 유형을 초기화 할 수 있습니다."를 의미합니다. 이론적으로매우 느리게 초기화 될 수 있음을 의미합니다. 필드를 건드리지 않는 정적 메서드를 호출하면 JIT가 유형을 초기화 할 필요가 없습니다.

실제로 는 클래스가 초기화되는 것을 의미한다 이전 은 그렇지 않은 것보다 -이 첫 번째 방법의 시작에 초기화하는 것이 괜찮아 를 사용합니다. 유형이 비교 하지 않는beforefieldinit유형의 초기화가 첫 직전에 발생하는 그들에 적용, 실제 사용.

따라서 다음이 있다고 가정합니다.

public static void DoSomething(bool which)
{
    if (which)
    {
        FirstType.Foo();
    }
    else
    {
        SecondType.Bar();
    }
}

두 유형이 모두 beforefieldinit적용 되었다면 (C #에서는 유형에 정적 생성자가없는 경우 기본적으로 수행됨) 메서드 시작시 둘 다 초기화됩니다 DoSomething(보통-보장되지 않음). 그들은이없는 경우 beforefieldinit 그들 중은 플래그를 기반으로 초기화됩니다.

이것이 싱글 톤 패턴을 구현할 때 정적 생성자를 사용하는 것이 일반적입니다 (빈 생성자라도!) .


"유형은 필드가 참조되기 전에 언제든지 초기화 될 수 있습니다." 정적 메서드를 실행하는 것도 사실입니까?
Royi Namir 2010 년

@RoyiNamir, CLI 사양에 따르면 BeforeFieldInit가 적용되면 "유형의 이니셜 라이저 메서드는 해당 유형에 대해 정의 된 정적 필드에 처음 액세스 할 때 또는 그 이전에 실행됩니다"라고 말합니다. 해당 속성이 누락 된 경우 (정적 .ctor) "해당 유형의 정적 또는 인스턴스 필드에 대한 첫 번째 액세스 또는 해당 유형의 모든 정적, 인스턴스 또는 가상 메서드의 첫 번째 호출"입니다. 따라서 정적 메서드가 다른 정적 필드를 참조하지 않는 한 적용된 BeforeFieldInit에 대해서는 사실이 아닙니다.
Arman McHitarian 2013 년

3
정적 생성자 (즉 beforefieldinit 플래그가없는 클래스)를 사용하면 성능이 저하된다는 사실을 발견했습니다. 특정 클래스의 정적 멤버를 자주 호출하면 런타임이 각 호출 전에 추가 검사를 수행하여 형식이 아직 초기화되었는지 여부를 테스트해야하는 것 같습니다. beforefieldinit는 이러한 검사를 피합니다. 몇 가지 벤치 마크는 beforefieldinit를 사용하여 약 50 % 더 빨랐습니다. codeproject.com/Articles/87991/…
Qwertie 2013

6

4.6에서 변경 될 것 같습니다.

https://github.com/dotnet/coreclr/issues/1193


굉장합니다. 이것은 필드를 초기화하는 마지막 순간까지 기다릴 것이라는 의미 beforefieldinit입니까 ( 유무에 관계없이 )?
James Ko

1
처음 사용하기 전에 모든 액세스 앞에 초기화 검사가 붙습니다. 그 후 다른 메서드가 jitted되면 생성 된 코드가 필드에 직접 액세스합니다. 원시 유형이면 JIT 시간 상수로도 사용할 수 있습니다.
OmariO

2
.Net 4.0을 시작으로 유형 초기화 변경 사항에 대한 Jon의 자세한 분석은 여기 .
RBT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.