성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] systemd for Developers I ; https:/...
[정성태] 엄밀히 object 타입의 인스턴스가 다른 타입으로 형변환 가능...
[정성태] 아래의 글에서 나오는 "Windows Application Pa...
[정성태] The history of calling conventions,...
[정성태] Secure and Deploy .NET Windows Form...
[정성태] Get Started with Milvus Vector DB i...
[정성태] cyberark/PipeViewer - A tool that...
[정성태] WinForms in a 64-Bit world – our st...
[정성태] 예제에서 SELECT_SQL도 내부적으로는 SqlCommand/...
[victor] SELECT_LINQ SELECT_SQL 같은 쿼리인...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>.NET 런타임에 따라 달라지는 정적 필드의 초기화 유무</h1> <p> 오호~~~ 처음 알았군요. ^^ 다음과 같이 간단한 코드를 만들어,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; namespace ConsoleApp1 { static class Program { <span style='color: blue; font-weight: bold'>static MyStatic _instance = new MyStatic();</span> static void Main(string[] args) { Console.WriteLine("Hello World!"); } } } internal class MyStatic { <span style='color: blue; font-weight: bold'>static MyStaticLevel2 _instance = new MyStaticLevel2();</span> public MyStatic() { <span style='color: blue; font-weight: bold'>Console.WriteLine("MyStatic.ctor");</span> } } internal class MyStaticLevel2 { public MyStaticLevel2() { <span style='color: blue; font-weight: bold'>Console.WriteLine("MyStaticLevel2.ctor");</span> } } </pre> <br /> .NET Framework과 .NET Core 환경에서 각각 실행하면 이런 결과가 나옵니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > [닷넷 프레임워크] MyStaticLevel2.ctor MyStatic.ctor Hello World! [닷넷 코어] Hello World! </pre> <br /> 그러니까, .NET Core의 경우 타입의 정적 필드를 초기화하는 코드가 실행되지 않은 것입니다. 그 이유에 대해서는 다음의 글에서 아주 자세한 답변을 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Why isn't this C# instance constructor being called, unless there is a reference to a non-static member? [duplicate] ; <a target='tab' href='https://stackoverflow.com/questions/52278729/why-isnt-this-c-sharp-instance-constructor-being-called-unless-there-is-a-refe'>https://stackoverflow.com/questions/52278729/why-isnt-this-c-sharp-instance-constructor-being-called-unless-there-is-a-refe</a> </pre> <br /> 정리해 보면.<br /> <br /> 자동 생성된 정적 생성자(cctor)는 beforefieldinit 속성이 붙어 있고, 이것은 런타임으로 하여금 해당 타입이 사용되기 전까지 초기화를 미루라는 의미를 가집니다. 하지만, .NET Framework 런타임은 그동안 이 속성을 무시하고 그냥 초기화를 진행했던 것이고, .NET Core 런타임부터 이 속성을 적극적으로 활용하기 시작한 것입니다.<br /> <br /> 이 문제를 해결하려면, 정적 멤버를 실제로 사용하는 코드를 넣거나, 아니면 정적 생성자를 사용자가 직접 정의해 두는 것(기본적으로 beforefieldinit 속성이 따라붙지 않음)입니다. 가령, 위의 경우 다음과 같이 소스 코드를 변경하면 됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using System; namespace ConsoleApp1 { static class Program { static MyStatic _instance = new MyStatic(); static void Main(string[] args) { Console.WriteLine("Hello World!"); } // 사용자가 정의한 정적 생성자에는 C# 컴파일러가 beforefieldinit 속성을 부여하지 않음 <span style='color: blue; font-weight: bold'>static Program() { // C# 컴파일러는 정적 필드에 대한 사용자 코드를 이곳으로 병합해서 빌드 }</span> } } internal class MyStatic { static MyStaticLevel2 _instance = new MyStaticLevel2(); public MyStatic() { Console.WriteLine("MyStatic.ctor"); } <span style='color: blue; font-weight: bold'>static MyStatic() { }</span> } internal class MyStaticLevel2 { public MyStaticLevel2() { Console.WriteLine("MyStaticLevel2.ctor"); } } </pre> <br /> 이런 면에서 봤을 때, 만약 .NET Core 이외의 환경에서도 사용할 라이브러리 프로젝트라면 일관성을 위해 정적 생성자를 통하도록 만드는 것이 권장됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > namespace ConsoleApp1 { static class Program { <span style='color: blue; font-weight: bold'>static MyStatic _instance;</span> static void Main(string[] args) { Console.WriteLine("Hello World!"); } static Program() { // 명시적으로 사용자 초기화 코드를 정적 생성자로 이동 <span style='color: blue; font-weight: bold'>_instance = new MyStatic();</span> } } } internal class MyStatic { <span style='color: blue; font-weight: bold'>static MyStaticLevel2 _instance;</span> public MyStatic() { Console.WriteLine("MyStatic.ctor"); } static MyStatic() { <span style='color: blue; font-weight: bold'>_instance = new MyStaticLevel2();</span> } } </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1694&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
6964
(왼쪽의 숫자를 입력해야 합니다.)