본문 바로가기

C#

CLR에서 돌아가는 언어를 뭔가를 만들어 보면서 https://github.com/pjc0247/ILIL 얼마 전에 ILIL이라는 이름으로, CLR환경에서 돌아가고 CIL로 컴파일되는 언어를 만들어보고자 하는 프로젝트를 진행했었다(개인적으로). 이번 프로젝트의 제작 의의는, 단순히 컴파일러 그 자체를 만들어보고, 결과물을 CIL로 출력해서, C# 또는 C++에서 콜해보는게 목적이었고, 어느 정도 작성한후에는 코드도 같이 Github에 공개할 예정이었다. (깃허브에 올려도 바다-나무님밖에 안보긴함)그리고 최종적으로는 완성된 ILIL 컴파일러를 이용해 아래 코드와 같이 Reflection.Emit을 대체할 물건을 만드려고 했다. var src = @" $loc0 = 0; for($loc1 = 0; $loc1 더보기
[C#] string과 String의 차이 String -> System.String -> .Net Framework 타입string - > C# 타입 C# 타입이 .Net 타입에 별명임 더보기
[MSIL] 런타임 property 구현하기 1. '_propertyName' 이름을 가지는 backing field를 만든다. ( C# 컴파일러가 만들어내는 실제 backing field 이름은 이것과 다르다 )2. 'get_propertyName' 이름을 가지는 getter 메소드를 만든다. 메소드가 MethodAttributes.SpecialName 속성을 가지는것을 기억하자.3. 'set_propertyName' 이름을 가지는 setter 메소드를 만든다. setter는 1개의 파라미터를 가진다. (value) 더보기
[MSIL] beforefieldinit beforefieldinit는 타입이 초기화(정적 생성자, cctor)되는 시점을 슈퍼-레이지하게 만들어준다. 슈퍼 레이지하다는것은, 스태틱 메소드중에 필드에 접근하지 않는 애는 호출이 되어도 초기화를 스킵한다는 뜻이다. 위 코드에서 PrintHello는 그냥 HelloWorld만 출력한다. 반면에 PrintHelloWithField는 HelloWorld를 찍은 뒤, 굳이 필드에 일부러 접근하는 동작을 가진다. 마지막으로 정적 생성자가 호출되는 시점을 알 수 있도록 CCTOR라는 메세지를 출력하도록 했다. 위의 코드를 실행하면 단순히 HelloWorld가 출력되는 모습을 볼 수 있는데, 이는 Foo 클래스는 beforefieldinit 속성을 가지고있기 때문에 PrintHello를 불러도 정적 생성자가 .. 더보기
[MSIL] for loop 첫번째 인자로 넘어온 int 숫자만큼 반복하는 메소드그냥 x86 어셈블리 지식을 더듬어 혼자 짠 코드라, 제대로된 C# 컴파일러가 빌드하는 코드와는 다를 수 있다. 더보기
[C#] Using static 사용하기 새로운 문법인 using static을 사용하면 네임스페이스 뿐만 아니라 static class도 축약하여 사용할 수 있다. 이 기능은 C# 6.0에서 추가된 기능이며, Visual Studio 2015부터 사용할 수 있다. 더보기
[C#] Thread.SpinWait와 SpinWait 구조체의 차이 .Net 에서는 SpinWait을 할 수 있는 두가지 방법을 제공한다첫번째는 Thread.SpinWait 메소드이고 두번째는 SpinWait구조체를 사용하는것이다. 이 두가지 방법은 busy waiting을 수행한다는점에서는 같은 역할을 하지만, 실제 동작에 있어서 몇가지 차이점을 가진다.일단 SpinWait 구조체는 Thread.SpinWait의 래핑이다. SpinWait는 Thread.SpinWait를 이용하여 구현되었다.Thread.SpinWait는 주어진 iterationCount만큼만 스핀한다, SpinWait의 SpinOnce는 딱 1회 스핀을 수행하는것이 아니다. 지금까지 얼마나 돌았는지 보고 적적한 스핀 횟수만큼 스핀하게 된다. (따라서 SpinWait를 미리 만들어놓고 재사용하는건 좋지 .. 더보기
[C#] Mixin 흉내내기 C#은 믹스인을 지원하지 않고, Java와 같은 인터페이스 기반의 다중 상속을 선택했다. 하지만 이 방법은 '구현'을 상속하지 못한다는 점에서 굉장히 불편한데, 아래의 예제에 어떤 경우에 불편한지 예제를 작성해 보았다. IPrintable 인터페이스는 디버그 용도 등을 위해 해당 클래스의 모든 프로퍼티들을 콘솔에 출력하기 위한 용도로 만들어졌다. 여기서 짜증나는 점은, Print 메소드는 무조건 직접 구현해야 한다는 것이다. 알다시피 C#은 런타임에 모든 프로퍼티의 이름, 값들을 리스트로 가지고있다. 그렇기에 사실 저렇게 직접 하나하나 다 찍어야 할 필요는 전혀 없다. 누가 대신 찍어줄수도 있다는 말이다. 위의 루비 예제는 mixin을 이용하여 모든 인스턴스 멤버의 값을 출력하는 Printable을 구현.. 더보기
[C#] Thread.Sleep의 await(Task) 버전 static async void Foo() { Console.WriteLine("hello"); await Task.Delay(1000); Console.WriteLine("world"); // 1 초후에 출력됨 } static void Main(string[] args) { Foo(); while (true) { Console.Read(); } } 더보기
[PostSharp] ReaderWriterSynchronized PostSharp의 ReaderWriterSynchronized기능을 이용하면 원본 코드의 수정 없이 이미 작성한 클래스를 Thread-Safe 하도록 만들 수 있습니다.명심해야 할 것은, PostSharp에서 제공하는 쓰레딩 모델들은 개발 편의성이 중시되어, 직접 제어되는 락보다 좋은 성능을 내지는 못합니다. 간단하게 카운터 클래스를 만들고 여러 스레드에서 동시에 반복적으로 카운트를 올리는 작업을 수행해 보도록 하겠습니다. class Foo { private int num {get; set;} = 0; public void Increase() { num++; } public int Read() { return num; } } class Program { static void Main(string[] a.. 더보기