[C# 4.0] 실용적인 관점에서 사용하는 dynamic 키워드

Visual Studio 2010 베타 2가 이 글을 쓰는 현 시점에 Express Edition과 함께 새롭게 공개되었습니다. .NET Framework 4.0과 더불어서 C# 4.0, Visual Basic .NET 10.0 등 언어들의 기능도 새롭게 향상되었으며, 특히 이목을 끄는 것은 Dynamic Language Runtime과 연동되는 Dynamic Programming에 관한 것입니다.


 


Dynamic Programming에 대해서, 철수네 소프트웨어 세상 블로그 (http://blogs.msdn.com/bkchung/)에 소개된 내용을 오래 전에 처음 포스팅을 했었지만 최근까지도 dynamic 키워드의 실용적인 사례를 찾지 못하고 있었습니다만, 최근 dynamic 키워드의 새로운 활용 가능성을 새롭게 발견하였습니다. 여러 시나리오가 있을 수 있겠지만 제가 오늘 이 포스트를 통해서 조명해보고자 하는 것은 Windows Forms가 제공하는 Web Browser와의 연동에 관한 것입니다.


 


Windows Forms가 버전 2.0에 들어서면서부터 매우 실용적인 컴포넌트를 새롭게 추가하였는데 바로 웹 브라우저 컨트롤이 그것이었습니다. 웹 브라우저 컨트롤은 단순히 브라우저로서도 활용할 수 있지만 잘 활용한다면 사용자 인터페이스를 웹 기반으로 업그레이드하는 것 또한 가능합니다.


 


하지만 COM Interop 프로그래밍에 기댈 수 밖에 없는 부분은 여전히 많았고, 당시의 C# 언어 사양만으로 COM Interop을 다루는데에는 비효율적이고 생산성이 떨어지는 부분이 많았습니다. 그런 이유로, 예전의 브라우저 컨트롤보다는 “조금 뛰어난” 수준으로 인지되는데에 그쳤습니다. 하지만 이번에 새로 소개되는 Dynamic Programming과 결합하면 매우 매력적인 프레임워크로 다시 거듭나게 됩니다.


 


Dynamic Programming을 시험해볼 좋은 자바스크립트 예제를 찾던 중, http://www.javascriptfreecode.com/34.htm 의 소스 코드를 발췌하여 Dynamic Programming 버전으로 만들어보았습니다.


 


본디 이 스크립트가 하는 일은 Internet Explorer가 고유하게 제공하는 웨이브 필터를 활용해서 텍스트를 화려하게 보일 수 있도록 치장하는 것입니다. 그러나 이 기능을, 여러 브라우저가 보는 페이지로서가 아닌, 온전히 Windows Forms 응용프로그램만을 위한 고유한 기능으로 바꾸어보도록 하겠습니다.


 



  1. 폼에 웹 브라우저 컨트롤을 새로 추가합니다.

  2. 웹 브라우저 컨트롤이 처음 보일 페이지를 about:blank 로 설정합니다. 빈 문서를 준비시키도록 하는데에 도움이 됩니다.

  3. 기본 이벤트인 DocumentCompleted 이벤트 핸들러를 새로 추가합니다.

  4. 아래의 코드를 작성합니다.



private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    dynamic document = this.webBrowser.Document.DomDocument;
    dynamic window = this.webBrowser.Document.Window.DomWindow;


    document.write(String.Format(@”
<!– Original Source: http://www.javascriptfreecode.com/34.htm –>

<

div>

{0}

</div>
“, window.prompt(“Please type a message to display: “, “Hello World!”)));


    Action DynWave = () =>
    {
        dynamic filter = document.getElementById(“Zittertext”).filters[0];
        if (filter.freq > 130)
            filter.freq = 15;
        filter.freq++;
        if (filter.phase > 50)
            filter.phase = 1;
        filter.phase++;
        if (filter.strength > 1)
            filter.strength = .1;
        filter.strength++;
    };


    Timer timer = new Timer();
    timer.Tick += (a, b) => DynWave();
    timer.Interval = 50;
    timer.Enabled = true;
}

 


위의 코드에서 우리가 관심있게 봐두어야 할 부분은 dynamic으로 선언한 변수 뒤에 나타나는 표현식들입니다. 컴파일러 기반의 언어들은 늘 그렇듯 문법의 정확성을 언제나 따지게 됩니다. C#도 분명히 그런 언어였습니다. 하지만 Dynamic Programming을 통하여 위와 같이 컴파일 시점에는 존재하지 않는 내용을 런타임 때에 유추해낼 수 있게 되었습니다.


 


여기서 의문점이 드는 것이 있는데, 그렇다면 이를 유추해내기 위해서 어떤 식으로 구현을 제공하는가에 대한 부분입니다. 이 부분에 대한 답은 바로 .NET Framework가 런타임 과정에서 정확한 객체 정보를 확인하기 위해서 사용하는 ObjectBinder에 있습니다. regasm 유틸리티로 등록해두었던 COM Interop Assembly나 Primary Interop Assembly에 대한 내용을 런타임 차원에서 관리하고, 이를 자동으로 연결하고 있는 것입니다. 직접 프로젝트에서 참조를 하지 않았다고 할지라도 그러합니다.


 


그리고 이러한 기능 위에 DLR과 더불어서 이미 LINQ에서 소개된 적이 있는 Expression Tree 해석 엔진에 의하여 C# 기준으로 작성된 코드를 Object Binder가 가지고 있는 정보와 일치시켜 정확한 기능을 하는 실제 코드를 컴파일 과정에서 작성하게 되는 것입니다. 이것은 형식 정보를 읽어서 매번 같은 컬렉션을 여러번 반복하면서 조회하는 Reflection 기반의 프로그래밍보다 훨씬 빠르게 동작하고, 훨씬 정확도가 높습니다.


 


위의 코드를 실행한 결과는 아래와 같습니다. 중간에 어떤 메시지를 표시할 것인지를 묻는 브라우저의 프롬프트 창에 원하는 메시지를 넣어보는 것도 괜찮을 것입니다.


 



 


Dynamic Programming에 대한 자세한 내용은 http://msdn.microsoft.com/en-us/library/dd264736(VS.100).aspx 의 내용을 참고하시면 도움이 될 것입니다.

[C# 4.0] 실용적인 관점에서 사용하는 dynamic 키워드”에 대한 5개의 생각

    • Internet Explorer 전용의 CSS Filter 기능 중에 Wave Filter라는 것이 있습니다. 웹 표준하고는 전혀 관계없는 부분이지만, 웹 2.0과 웹 표준이 등장하기 이전에 한 시대를 풍미했었던 DHTML 시절의 물건입니다. ㅎㅎ

      그리고 따옴표를 “”로 표기한 것은 문자열의 시작을 보시면 @” 으로 시작하고 있습니다. 이렇게 시작하는 문자열을 Verbatim String이라고 하고, 안에 어떤 문자가 오든 개의치 않게 지시할 수 있습니다만 단 하나 예외가 있다면 따옴표에 관한 것입니다. 따옴표를 한번만 쓰면 닫는 것으로 해석되기 때문에, ” 으로 이스케이프 처리를 하는것이 아니라 이 경우에는 특별히 “” 로 이스케이프 처리를 하게 된 것으로 결국 ” 로 실제 문자열에 나타나게 됩니다. 🙂

  1. document.write() 호출 부분 같은 데를 보면, C# 코드와 자바스크립트 코드의 모양새가 거의 비슷해서 언어의 경계가 희미해보일 정도네요. 놀랍습니다 @.@

    • 예제로 사용한 언어가 C#이었기 때문에 조금 달라지는 점도 있긴 했지만, JScript.NET이 DLR에 바인딩되어 사용된다면 원래 사용하던 JavaScript와 동일한 구문을 그대로 사용할 수도 있을것 같아요. 여러모로 흥미로운 아이템이라고 생각합니다. ㅎㅎ

댓글 남기기