성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] VT sequences to "CONOUT$" vs. STD_O...
[정성태] NetCoreDbg is a managed code debugg...
[정성태] Evaluating tail call elimination in...
[정성태] What’s new in System.Text.Json in ....
[정성태] What's new in .NET 9: Cryptography ...
[정성태] 아... 제시해 주신 "https://akrzemi1.wordp...
[정성태] 다시 질문을 정리할 필요가 있을 것 같습니다. 제가 본문에...
[이승준] 완전히 잘못 짚었습니다. 댓글 지우고 싶네요. 검색을 해보...
[정성태] 우선 답글 감사합니다. ^^ 그런데, 사실 저 예제는 (g...
[이승준] 수정이 안되어서... byteArray는 BYTE* 타입입니다...
글쓰기
제목
이름
암호
전자우편
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 Internals Cookbook Part 11 - Various C# riddles</h1> <p> 이번에도 .NET Internals Cookbook 시리즈의 11번째 글을 번역한 것입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .NET Internals Cookbook Part 11 - Various C# riddles ; <a target='tab' href='https://blog.adamfurmanek.pl/2019/04/27/net-internals-cookbook-part-11/'>https://blog.adamfurmanek.pl/2019/04/27/net-internals-cookbook-part-11/</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>75. TimeSpan의 분해능은?</div> <br /> <a target='tab' href='https://learn.microsoft.com/en-us/dotnet/api/system.timespan'>문서</a>에 따라,<br /> <br /> <div style='BACKGROUND-COLOR: #ccffcc; padding: 10px 10px 5px 10px; MARGIN: 0px 10px 10px 10px; FONT-FAMILY: Malgun Gothic, Consolas, Verdana; COLOR: #005555'> The value of a TimeSpan object is the number of ticks that equal the represented time interval. A tick is equal to 100 nanoseconds, or one ten-millionth of a second.<br /> </div><br /> <br /> 100 나노초 단위입니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>76. AppDomain 간에 공유되는 것은?</div> <br /> 다음의 정보들이 공유됩니다.<br /> <br /> <ul> <li>도메인 중립 타입의 객체들</li> <li>PropertyInfo와 같은 리플렉션 타입들</li> <li>문자열</li> <li>스레드</li> </ul> <br /> 다중 도메인 간에 공유되는 객체를 일컬어 "marshal-by-bleed"라고 합니다. 이런 타입들은 특히 동기화를 위한 lock을 걸 때 더 주의를 요합니다. 서로 다른 AppDomain 간의 동기화를 할 수 있으므로 한편으로는 유용하긴 하지만 무심코 lock(typeof(Foo))와 같은 식으로 리플렉션 타입에 lock을 거는 경우 전체 AppDomain 들 간에 동기화가 걸리므로 다중 웹 애플리케이션을 호스팅하는 ASP.NET과 같은 환경에서 성능 저하를 유발할 수 있습니다.<br /> <br /> 참고로, 다음은 CrossDomainData 타입의 인스턴스를 AppDomain 간에 공유해 값을 조작하는 <a target='tab' href='https://stackoverflow.com/questions/2206961/sharing-data-between-appdomains/11665093#11665093'>예제</a>입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > using Endjin.Assembly.ChangeDetection.Infrastructure; using System; using System.Linq; using System.Reflection; using System.Runtime; class Program { <span style='color: blue; font-weight: bold'>[LoaderOptimization(LoaderOptimization.MultiDomain)]</span> static public void Main(string[] args) { for (int i = 0; i < 10000; i++) { var other = AppDomain.CreateDomain("Test" + i.ToString(), AppDomain.CurrentDomain.Evidence, new AppDomainSetup { }); DomainGate gate = (DomainGate)other.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(DomainGate).FullName); CrossDomainData data = new CrossDomainData(); data.Input = Enumerable.Range(0, 10).ToList(); DomainGate.Send(gate, data); Console.WriteLine("Calculation in other AppDomain got: {0}", data.Aggregate); } } } class DomainGate : MarshalByRefObject { public void DoSomething(int gcCount, IntPtr objAddress) { if (gcCount != ObjectAddress.GCCount) { throw new NotSupportedException("During the call a GC did happen. Please try again."); } CrossDomainData data = (CrossDomainData)PtrConverter<Object>.ConvertFromIntPtr(objAddress); foreach (var x in data.Input) { Console.WriteLine(x); } data.Aggregate = data.Input.Aggregate((x, y) => x + y); } public static void Send(DomainGate gate, object o) { var old = GCSettings.LatencyMode; try { GCSettings.LatencyMode = GCLatencyMode.Batch; // try to keep the GC out of our stuff var addandGCCount = ObjectAddress.GetAddress(o); gate.DoSomething(addandGCCount.Value, addandGCCount.Key); } finally { GCSettings.LatencyMode = old; } } } </pre> <br /> Main 메서드의 <a target='tab' href='https://www.sysnet.pe.kr/2/0/10948'>LoaderOptimization.MultiDomain</a> 옵션을 제거하면 CrossDomainData data;를 공유할 수 없어 다음과 같은 예외가 발생합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Unhandled Exception: System.InvalidCastException: [A]CrossDomainData cannot be cast to [B]CrossDomainData. Type A originates from 'ConsoleApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\temp\ConsoleApp1\bin\Debug\ConsoleApp1.exe'. Type B originates from 'ConsoleApp1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'C:\temp\ConsoleApp1\bin\Debug\ConsoleApp1.exe'. at DomainGate.DoSomething(Int32 gcCount, IntPtr objAddress) in C:\temp\ConsoleApp1\Program.cs:line 54 at DomainGate.DoSomething(Int32 gcCount, IntPtr objAddress) at DomainGate.Send(DomainGate gate, Object o) in C:\temp\ConsoleApp1\Program.cs:line 75 at Program.Main(String[] args) in C:\temp\ConsoleApp1\Program.cs:line 30 </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>77. callback을 해제하지 않은 상태에서 Timer에 대한 별도의 참조가 없다면 삭제될까요?</div> <br /> 다음의 예제 코드에서 확인할 수 있듯이,<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; using System.Threading; public class Program { public static void Main(string[] args) { var stateTimer = new Timer(t => Console.WriteLine("Timer!"), null, 50, 50); Thread.Sleep(70); <span style='color: blue; font-weight: bold'>stateTimer = null; GC.Collect(); GC.WaitForPendingFinalizers();</span> Thread.Sleep(1500); } } /* 출력 결과 (한 번만 출력) Timer! */ </pre> <br /> 삭제됩니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>78. delegate {...}와 delegate() {...}의 차이점</div> <br /> 전자의 경우는 어떤 인자라도 받을 수 있지만 후자의 경우에는 인자가 없어야만 합니다. 확인은 다음의 코드로.<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 Program { public delegate void Foo(); public delegate void Bar(int x); public class Program { public static void Main(string[] args) { Foo a = delegate { }; Bar b = delegate { }; Foo c = delegate () { }; // Error CS1593 Delegate 'Bar' does not take 0 arguments Bar d = delegate () { }; } } } </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>79. C# 어셈블리에서 DllMain 함수를 가질 수 있을까?</div> <br /> 사실 C/C++에서의 DllMain과 정확히 일치하는 함수를 구현할 수는 없지만 그와 유사한 역할을 하는 메서드는 IL로 구현할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > .assembly extern mscorlib { .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. .ver 4:0:0:0 } .assembly 'f66978ab-21bd-416d-b1fd-2cc8d4467cef' { .hash algorithm 0x00008004 .ver 0:0:0:0 } .module 'f66978ab-21bd-416d-b1fd-2cc8d4467cef.dll' // MVID: {15C95762-8B92-4BE6-9ABD-A280C050496E} .imagebase 0x10000000 .file alignment 0x00000200 .stackreserve 0x00100000 .subsystem 0x0003 // WINDOWS_CUI .corflags 0x00000001 // ILONLY // Image base: 0x015B0000 <span style='color: blue; font-weight: bold'>.method public hidebysig specialname rtspecialname void .cctor() cil managed { .maxstack 8 IL_0000: nop IL_0001: ldstr "Module initializer!" IL_0006: call void [mscorlib]System.Console::WriteLine(string) IL_000b: nop IL_000c: ret }</span> .class public auto ansi beforefieldinit Program.Program extends [mscorlib]System.Object { .method public hidebysig static void Main(string[] args) cil managed { // .entrypoint .maxstack 8 IL_0000: nop IL_000c: ret } // end of method Program::Main .method public hidebysig specialname rtspecialname instance void .ctor() cil managed { // .maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: nop IL_0007: ret } // end of method Program::.ctor } // end of class Program.Program </pre> <br /> ilasm.exe로 컴파일하고 실행하면 "Module initializer"를 출력하는 것을 볼 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C:\temp> <span style='color: blue; font-weight: bold'>ilasm test.il /quiet</span> test.il(21) : warning : Non-static global method '.cctor', made static C:\temp> <span style='color: blue; font-weight: bold'>test</span> Module initializer! </pre> <br /> .NET Reflector 등으로 확인해 보면 <Module> 타입의 cctor로 등록된 것을 확인할 수 있습니다. <br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static <Module>() { Console.WriteLine("Module initializer!"); } </pre> <br /> 예전에 저도 Module 타입에 대해 다룬 적이 있었죠. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 닷넷 - <Module> 클래스의 용도 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11335'>http://www.sysnet.pe.kr/2/0/11335</a> </pre> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>80. Nullable<T> 타입을 직접 구현할 수 있을까?</div> <br /> Nullable 타입은 특별하게 대우를 받기 때문에 그와 동일한 타입을 C#으로 구현할 수는 없습니다. 대신 struct로 유사하게 구현할 수는 있는데요.<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 Program { public class Program { public static void Main(string[] args) { Nullable<int> i = 5; Console.WriteLine(i.GetType()); <span style='color: blue; font-weight: bold'>// System.Int32</span> OwnNullable<int> j = 6; Console.WriteLine(j.GetType()); <span style='color: blue; font-weight: bold'>// OwnNullable`1[System.Int32]</span> i = null; <span style='color: blue; font-weight: bold'>// Error CS0037 Cannot convert null to 'OwnNullable<int>' because it is a non - nullable value type // j = null;</span> } } } struct OwnNullable<T> where T : struct { private T field; public OwnNullable(T value) { field = value; } public static implicit operator OwnNullable<T>(T value) { return new OwnNullable<T>(value); } } </pre> <br /> 보는 바와 같이 GetType의 결과도 런타임의 배려가 있다는 것을 확인할 수 있습니다. 게다가 순수 struct이기 때문에 null 대입이 안 되는 등의 문제가 있습니다.<br /> <br /> <hr style='width: 50%' /><br /> <br /> <br /><div style='font-size: 12pt; font-family: Malgun Gothic, Consolas; color: #2211AA; text-align: left; font-weight: bold'>81. 제한된 접근 제한자가 지정된 타입을 보다 공개된 접근 제한자를 갖는 타입에 상속할 수 있을까?</div> <br /> 일반적으로는 다음과 같이 오류가 발생하지만,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class Foo { private class IBar { } // Error CS0060 Inconsistent accessibility: base class 'Foo.IBar' is less accessible than class 'Foo.Bar' //public class Bar : IBar //{ //} } </pre> <br /> 인터페이스로는 가능합니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > public class Foo { private interface IBar { } public class Bar : IBar { } } </pre> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1445&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> </h1><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1374
(왼쪽의 숫자를 입력해야 합니다.)