.NET Framework/BUNDLE2010. 12. 15. 03:39
 회차
[.NET] Code Securit(Spear and Shield) : 01. DisAssembler
[.NET] Code Securit(Spear and Shield) : 02. Obfuscation

[.NET] Code Securit(Spear and Shield) : 03. Dotfuscator Program Comparison #1
[.NET] Code Securit(Spear and Shield) : 04. Dotfuscator Program Comparison #2
[.NET] Code Securit(Spear and Shield) : 05. Obfuscation Design Tip And Notabilia
[.NET] Code Securit(Spear and Shield) : 06. Security Tools : Strong Name Tool
04| 코드 보안(창과 방패) - Dotfuscator 프로그램 비교 #2
구독자 여러분 안녕하세요
이번 회차에서는 지난 포스팅에 이어 Control Flow, String Encryption, Pruning 기능에 대서 알아보도록 하겠습니다.  예제를 위해서 지난 회차에서 사용했던 예제코드를 인용하도록 하겠습니다.

[코드1] 변환 대상 예제 코드
namespace ObfuscationEx
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("안녕하세요 방갑습니다.");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("100 + {0}의 합은? {1}", i, 100 + i));
            }
            Console.WriteLine();
            Console.WriteLine(new People().ToString());
        }
    }
    class People
    {
        private string NameKor = "정은성";
        private string NameEng = "Jeong Eun Seong";

        public override string ToString()
        {
            return string.Format("한글 이름은? {0} 영문 이름은? {1}", NameKor, NameEng);
        }
    }
}

2.Control Flow
Control Flow는 프로그램의 조건, 분기, 반복문과 같은 논리적 구조를 스파케티 코드화하여 구조를 어렵게 변경을 하게 됩니다. 이과정에서는 성능 저하가 발생 할수 있지만 코드의 가독성을 떨어트리면서 분석이 어려울 수 있습니다.

보통 실무 프로젝트를 가지고 Control Flow를 적용을 했었는데요. 구독자 여러분들께 소개해드리고자 간단한 코드를 가지고 테스트 중에 흥미로운 사실을 알게 되었습니다. Control Flow 기능이 생각보다 강력 했던 이유인지 역에섬블러 프로그램 마저 해독하지 못하는 상황이 나타났습니다. 의도 했던 코드는 Main 메소드 인데요.

간단한 코드임에 불구하고 Control Flow의 영향으로 인해 최고?! 라고 불리는 Red Gate's .Net Reflector에서도 확인 해 볼 수 없었습니다.  훗..코드가 복잡했나?

[그림 1] Control Flow 적용


그래도 여러분들께 소개를 해드려야할것 같아 더 간단한 코드를 가지고 비교를 해보도록 하겠습니다.
비교하기 위해 의미 없는 임시코드를 다음과 같이 작성 하였습니다.

[코드 1] Control Flow 비교용 샘플 코드
private static int testMethod()
{
      int n = 0;
      if (n == 0)
      {
           n = string.Compare("정은성", "Jeong");
      }
      return n;          
}

아주 심플한 코드입니다. 위 논리적 구조가 어떤 형태로 변경이 되는지 살펴보도록 하죠.

[그림 2] Control Flow 적용 비교

Clontrol Flow를 적용을 해보았는데요.
적용 전후를 보시고  " 에이~ 코드 제어 흐름만 변경 됬자나? ",  " 별거 없네요. "  이런 생각이 드실것 같아요.

이해를 돕고자 단순화 한 코드이며 큰 의미는 없습니다. 그래도 정말 어떻게 변경이 되는지 보여드려야 할것 같아요.
그래서 dotfuscator 유저가이드 내용을 발취하였습니다. 

[사례 1-1] Control Flow 적용 전 [ 출처 : dotfuscator's user guide ]
public int CompareTo(Object o) {
    int n = occurrences – ((WordOccurrence)o).occurrences;
    if (n == 0) {
        n = String.Compare(word, ((WordOccurrence)o).word);
    }
    return(n);
}

[사례 1-1] Control Flow 적용 후 [ 출처 : dotfuscator's user guide ]
public virtual int _a(Object A_0) {
    int local0;
    int local1;
    local0 = this.a – (c) A_0.a;
    if (local0 != 0) goto i0;
    goto i1;
    while (true) {
        return local1;
        i0: local1 = local0;
    }
    i1: local0 = System.String.Compare(this.b, (c) A_0.b);
    goto i0;
}

내용을 보시면 " 아~ 이렇게 읽기 어려운 구조로 변경이 되는구나!! " 라고 느낌을 받으실것 같아요?
저만 그런가요? 

이렇게 변경이 되었지만 주의 해야할 부분이 존재를 합니다. 앞서 말씀 드린적이 있는데요.
이기능을 사용하게 되면 가독성을 떨어지지만 속도 측면에서 성능이 저하가 될 우려가 있습니다.
따라서 필요에 따라 부분적으로 Control Flow 기능을 적용하실 필요가 있음을 알려드립니다. : )

이어서 기능에 대해서 알아보도록 하겠습니다.
이 기능 또한 Rename 기능과 같은 패턴의 오퍼레이션을 가지고 있고 다음과 같습니다.

[그림 3-1] Dotfuscator 프로그램 Control Flow 기능 화면 - Exclude 영역


① 텝 메뉴 : Control Flow기능은 2가지 기능으로 구성 되어 있습니다.
     - Exclude : Control Flow 적용시 배제 될  적용 대상 설정
     - Options : Control Flow 적용시 옵션으로 가독성 강도에 대해 High, Medium, Low로 구성

② 트리영역 : 해당 어셈블러의 구조를 제공하며 Control Flow 적용 대상을 제외하여 빌드가 가능합니다.
③ 적용 규칙 영역 : 해당 영역은 배제 가능한 규칙을 정규식을 정의 하여 적용 대상을 제외 하여 빌드 가능합니다.
                                적용 규칙에 대해서 궁금하시면 별도로 문의 바랍니다 : )


[그림 3-2] Dotfuscator 프로그램 Control Flow 기능 화면 - Options 영역


Control Flow 기능은 해당 코드를 스파게티화 하면서 가독성 측면과 성능 측면에서 반비례 성향을 알수 있었는데요.
많은 스레드를 요구를 한다거나 엑세스 타임이 짧은 프로세스를 처리해야 한다면 필요에 따라서 배제 대상을 지정하여 빌드를 하셔야 합니다.

이렇게 가볍게 리뷰를 해보았는데요 이기능을 적용해야 한다면 개발 중신 프로그램의 특정부분을 어떻게 배제 해야할지 조금이라도 도움이 되셨기를 바랍니다.

이어서 String Encryption 기능에 대해서 살펴보도록 하겠습니다.

3. String Encryption
흔히 크래커는 리버싱 하려고 할때 가장 쉽게 접근이 가능한 메세지 부분을 검색을 하는 편인데요. 이기능은 이러한 케이스를 조금이라도 접근을 하지 못하도록 해당 문자열을 암호화하여 문자열을 찾을수 없도록 하는 기능입니다.

간단한 예제를 통해 변경 전후를 살펴보도록 하며 이어서 사용방법에 대해서 알아보도록 하겠습니다.

[코드2-1] String Encryption 적용 전 
Console.WriteLine("안녕하세요 방갑습니다."); 

[코드2-2] String Encryption 적용 후 
Console.WriteLine(a("쪼좾뛀ꇄꋆ뿈믊꓌껎￐냒뫔뫖飚軜럞胠釢闤짦ꓨꫪ꣬뫮뷰", num2));

적용 후의 형태를 보시면 깨진 문자열을 보이는데.
" 파일 포맷이 인코딩이 잘못됬나?" , " 저렇게 깨진 문자를 심어두면 프로그램이 돌아갈까? " 라고 
의심 스러울것 같은데. 걱정 안하셔도 됩니다.

아무쪼록 알수 없는 문자열 형태로 변경되어 있는데요. 내부적 로직은 리버싱을 통해 분석을 해봐야 알수 있겠지만
a라는 메소드와 인수에 의해 복원이 되는것으로 추측 됩니다.

이기능 또한 어떻게 사용하는지 알아봐야할것 같은데요. 해당 기능 또한 Control Flow기능과 유사한 인터페이스지만 다른 오퍼레션을 가지고 있습니다.

[그림 4] Dotfuscator 프로그램 String Encryption 기능 화면



보시는 화면과 같이 구성은 Rename, Control Flow과 달리 Include 텝만 구성이 되어있고 또한 배제해야할 대상이 아니라 적용 해야할 대상을 지정을 해줘야만 난독화가 가능합니다.

① 트리 영역 : 해당 어셈블러의 구조를 제공하며 String Encryption 적용 대상을 지정해야만 빌드가 가능합니다.
적용 규칙 영역 : 해당 영역은 적용해야할 규칙을 정규식을 통해 정의 하여 적용하면 빌드 가능합니다.
                               이 기능에 대해서 궁금하신점 있으시면 문의 바랍니다 : )

String Encryption 기능은 해당 문자열을 알수 없는 형태로 변경함으로써 크래커에게 리버싱을 하기 어렵도록 제공을 하고 있는데요. 막강한 기능에도 불구하고 타입체킹, 리플렉션, 통신 등 케이스의 경우 프로그램이 정상적으로 작동하지 않으므로 가능한 유저가이드를 숙지하시고 적용하시길 바랍니다. 만약 번그럽거나 내용이 어려우시다면 다음 회차에서 소개 되는 "난독화 디자인 팁 & 주의사항해야 할 사항" 포스팅을 보시면 조금이라도 도움이 되실것 같습니다.

드디어 소개해드릴 마지막 기능에 도달했습니다. 그럼 Pruning(Removal) 기능에 대해 살펴보도록 할까요?

4. Pruning(Removal)
지난 회차에서 소개를 해드린 내용을 인용한다면 " 프로그램을 좀더 빠르게 실행하도록 돕는 기능! " 라고 말씀 드릴 수 있습니다. 그렇다면 " 도대체 어떤 기능이길래? 속도가 향상이 된다는것인지 "  궁금증을 가지시는분이 계실것 같은데요. 이 기능을 적용하게 된다면 실제 작성된 코드 중 사용하지 않는 코드를 제거하게 됩니다. 

즉, 필드, caller에 의해 반환 받는 시그니처, 생성자(.ctor) 등을 스택에서 제거하므로 속도를 향상이 시킬 수 있습니다.

그럼 간단한 예제를 통해 어떻게 달라지는지 살펴보고 사용 방법에 대해서 알아보도록 하겠습니다.

[코드 3] Pruning(Removal) 예제 코드 
namespace ObfuscationEx
{
    class Program2
    {
        Program2()
        {
            string test = "";
        }
        static void Main(string[] args)
        {
            string test = "";
            Console.Write("안녕하세요 구독자 여러분 : )");
            string test2 = MyTestMethod();
        }
        public static string MyTestMethod()
        {
            return "test";
        }
    }


간단한 예제를 통해 변경 전후를 살펴보도록 하며 이어서 사용방법에 대해서 알아보도록 하겠습니다.

[그림 5-1] Pruning(Removal) 적용 전 


여기서 유심히 살펴보실 내용은 빨간색 테투리 영역 입니다.  다음 적용 후와 비교를 해보시길 바랍니다.

[그림 5-2] Pruning(Removal) 적용 후 


[코드 4] Pruning(Removal) 적용 전(Main 메소드 일부)
string test = "";
Console.Write("안녕하세요 : )");
string test2 = MyTestMethod();


[그림 5-3] Pruning(Removal) 적용 후  


적용 전후를 정리해보면...
1. 실제 사용하는 클래스와 사용하지 않는 클래스 영역 정리
2. 메소드와 필드, 생성자(.ctor()) 영역 정리
3. 반환 메소드의 타입이 사용이 되지 않는 영역 정리

이기능 또한 어떻게 사용하는지 알아봐야할것 같습니다.

[그림 6-1] Dotfuscator 프로그램 Pruning(Removal) 기능 화면
                Include Triggers, Conditional Includes 영역



① 텝 메뉴 : Pruning(Removal)기능은 3가지 기능으로 구성 되어 있습니다.
     - Include Triggers : Pruning 적용하기 위한 트리거 설정
     - Conditional Includes : Input 어셈블러에 관련된(DLL, 리소스) 모듈등 어셈블러간의 모든 종류의 공유하는 경우
                                           Pruning 조건을 설정 가능 합니다. 
     - Options : Pruning 적용시 어떤 어셈블러를 제거 해야할지 XML/HTML로 보고서를 생성 기능

② 트리영역 : 해당 어셈블러의 구조를 제공하며 Pruning 적용 대상을 트리거 형태로 지정하여 빌드가 가능합니다.
③ 적용 규칙 영역 : 해당 영역은 적용해야할 규칙을 정규식을 통해 정의 하여 적용하면 빌드 가능합니다.
                                적용 규칙에 대해서 궁금하시면 별도로 문의 바랍니다 : )

[그림 6-2] Dotfuscator 프로그램 Pruning(Removal) 기능 화면 - Options 영역


옵션 영역은 어떤 어셈블러를 제거를 할것인지에 대해 XML 형태로 제거 보고서를 생성하는 기능을 제공합니다.
입력된 어셈블러의 구성원들을 어떻게 정리를 할것인지를 설명해주며 필요에 따라 XML이 아닌 HTML로 변환이 가능하며 유용하게 사용이 가능합니다.

Pruning(Removal) 기능은 흔히 개발을 하시다보면 의도하지 않게 불필요한 코드를 남겨 두거나 의미 없는 코드를 반환 하는 경우가 있는데요. 리펙토링을 통해 정정이 가능하지만 미쳐 발견을 하지 못햇을때 유용하지 않을까 하는 개인적인 생각이 듭니다.

그외 많은 기능들이 존재를 하는데요. 자세한 사항은 유저 가이드를 참고 하시길 바랍니다.

참고 문헌

- Dotfuscator 4.0 : : http://msdn.microsoft.com/ko-kr/library/ms227240.aspx
- Dotfuscator 4.0 유저 가이드( ※ 저작권 문제로 파일은 첨부 할수 없습니다. )
 
포스팅을 마치며...

지금까지 Dotfuscator프로그램의 기능들에 대해서 살펴보았는데요. 여러분들께 유익한 내용을 전달해드리고자 나름?! 알차게 구성을 했는데요. 어떠셨는지 모르겠네요. 아직 난독화를 하지 못하셨다면 지금 바로 적용해보세요. 

앞으로 회차가 더 있는데, 관심있게 봐주실거죠?

더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.
감사합니다.

정은성 드림
Posted by LenAWeb

댓글을 달아 주세요

  1. 프럼헬

    정은성님 그동안 포스팅하신 글들을 보고 크게 도움받고 있습니다. 감사합니다.
    다름이 아니고 String Encryption 기능에서 타입체킹, 리플렉션, 통신등에서 정상적으로 동작하지 않는다고 하셨는데
    DB로 데이타를 보낼때도(입력값등) 정상적으로 동작하지 않는다는 말씀이신가요?
    String Encryption 기능에서 적용규칙을 만드는 방법을 알고 싶은데 간단하게라도 설명을 부탁드립니다.
    klass77@naver.com

    2010.12.22 03:30 [ ADDR : EDIT/ DEL : REPLY ]
    • 우선, 블로그를 방문해주셔서 감사합니다.
      타입체킹과 String Encrption 기능은 다각도의 의미를 가질수 있습니다.
      그중 해당 타입 혹은 메소드가 어트리뷰트에 의해 무언가가 조작이 된다면 그문자열이 함부러 변경이 되선 안된다는 의미로 타입체킹이라고 명시하였습니다.

      리플렉션 또한 스트링에 의한 멤버변수, 메소드, 속성등을 접근 하려고 할때 암호화 되어 버린다면 문제가 되겠죠.

      통신에 관련된 메세지 전송이나 통신 주소 혹은 연결문자열와 같은 문자열이 암복호화가 가능한 암호화 기술이 아닌 어셈블를 난독화 하기 위한 암호화라면 그 행위에 대해 보장을 받을 수 없고 실행이 된다고 해도 비정상적으로 운영될 가능성이 있습니다.

      정규식을 이용한 방법은 바로 회신 해드릴 순 없구요.시간이 한가해지면 보내드리도록 하겠습니다. 더 궁금하신점이 있으시면 아래 URL을 통해 회신 바랍니다.
      http://blog.tobegin.net/notice/1

      2010.12.24 00:07 신고 [ ADDR : EDIT/ DEL ]

.NET Framework/BUNDLE2010. 11. 30. 03:33
 회차
[.NET] Code Securit(Spear and Shield) : 01. DisAssembler
[.NET] Code Securit(Spear and Shield) : 02. Obfuscation

[.NET] Code Securit(Spear and Shield) : 03. Dotfuscator Program Comparison #1
[.NET] Code Securit(Spear and Shield) : 04. Dotfuscator Program Comparison #2
[.NET] Code Securit(Spear and Shield) : 05. Obfuscation Design Tip And Notabilia
[.NET] Code Securit(Spear and Shield) : 06. Security Tools : Strong Name Tool
03| 코드 보안(창과 방패) - Dotfuscator 프로그램 비교 #1
구독자 여러분 안녕하세요
오늘 포스팅은 Visual Studio와 동고동락한 10년지기 친구?!를 소개(프로그램)을 소개 할까 합니다.
바로 Dotfuscator 프로그램 인데요. Dotfuscator 프로그램은 Visual Studio 2003 버전 부터 일부 기능에 한해 Add-in 버전으로 번들이 제공 되었습니다. 이 프로그램은 Developer Licenses User당  250만원 상당의 상용 프로그램 인데요. 난독화 프로그램에 대해서 잘 모르시는 분들이 계신것 같아 준비 해봤습니다.

자! 이제 Dotfuscator에 대해서 프로그램을 비교 할때가 왔습니다. 앞서  축소된 기능이 제공 되고 있다고 말씀 드렸는데요. 실제로  어떤 버전이 존재를 하는지 살펴보도록 하겠습니다.

Dotfuscator은 3가지 버전으로 나눠지고 있는데요.

* Dotfuscator 프로그램 종류
- Dotfuscator Professional Edition
- Dotfuscator Enhanced Community Edition
- Dotfuscator Community Edition


자세한 정보를 확인해보시려면 아래를 참고 해주십시오.

MSDN에서 명시된 내용의 기준으로 본다면 기능들이 버전별로 지원 여부가 다른것을 확인 할 수 있습니다.
그럼 어떤 기능들이 있는지 살펴볼까요?

* Dotfuscator 난독화 프로그램은 어떤 기능(옵션)을 가지고 있나요?
Dotfuscator 프로그램은 크게 9가지 기능을 가지고 여러 옵션을 지원(Professional Edition 기준)을 하고 있습니다.

1. Renaming
난독화 프로그램에서는 멤버 변수, 함수이름, 클래스등의 시스템 고유 문자형(a,b,c,1,2,3,.....등)로 이름 바꾸기기능이 제공합니다. 이는 혼란하기 쉬운 시퀸스 이름으로 바꾸기 때문에 역어셈블러 해독에 어려움을 줄수 있습니다

2. Control Flow obfuscation
개발 프로그램의 조건, 분기, 반복과 같은 논리적 구조를 스파게티 코드화(어려운 구조로 변경)를 제공합니다. 이 과정에서 성능 저하가 발생 할 수 있지만 코드의 분석은 매우 어려울수 있습니다.
이 기능은 Professional Edition 버전에서만 지원합니다.


3. String Encryption
크래커는 프로그램을 변조하기 위해서 주요 문자열을 검색하여 변조를 하게 됩니다. 역어셈블러를 방지하고자 문자열 또한 암호화여 디컴파일 시도시 해당 문자열을 찾을수 없도록 기능을 제공합니다

4. Enhanced Overload Induction
Professional Edition 버전의 확장 기능으로써 코드 내의 필드와 메소드 반환 유형을 변경함으로 코드를 이해 못하도록 기능이 제공됩니다.

5. Pruning(Removal)

작은 응용프로그램 더욱 빨리 실행하도록 돕는 기능입니다. 작성된 코드중 사용하지 않는 코드를 제거 하므로써 속도를 향상 시킵니다.

6. Assembly Linking
여러 어셈블러 파일을 하나의 파일로 병합하여 작고 간단한 배포 시나리오를 제공합니다.

7. Watermarking
워터마크는 무단 사본을 추적하는데 사용할수 있는 방법으로 저작권 정보 또는 고유 식별과 같은 정보를 런타임 동작에 여향을 주지 않고 삽입할수 있는 기능을 제공 합니다.

8. Incremental Obfuscation
난독 프로그램을 실행하는 동안 이름 매핑 레코드 생성, 분산된 난독 프로그램 통합 기능 제공합니다.

9. Debugging Obfuscated Code
난독화된 프로그램 배포 이후 문제 발생시 해당 스택을 원래 이름으로 대체 하여 제공(Professional Edition)

기능에 대한 자세한 설명은 유저 가이드를 참고 하시길 바라며 포스팅을 통해 전반적인 내용을 다뤄 볼수 없기 때문기에  일부 기능에 한해(Renaming, Control Flow, String Encryption, Pruning) 알아보도록 하겠습니다.

* 그럼 빨리 난독화 도구 사용하는 방법좀 알려주세요!
난독화에 앞서 비교 분석을 하려면 난독화 하고하는 대상 코드가 필요하겠죠?

[코드 1] 변환 대상 예제 코드
namespace ObfuscationEx
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("안녕하세요 방갑습니다.");
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(string.Format("100 + {0}의 합은? {1}", i, 100 + i));
            }
            Console.WriteLine();
            Console.WriteLine(new People().ToString());
        }
    }
    class People
    {
        private string NameKor = "정은성";
        private string NameEng = "Jeong Eun Seong";

        public override string ToString()
        {
            return string.Format("한글 이름은? {0} 영문 이름은? {1}", NameKor, NameEng);
        }
    }
}

적절한 코드가 완성이 되었습니다. 그럼 이제 변환을 해볼까요? 두근두근♥

1. Renaming
기능 명에서도 알수 있듯이 무언가를 바꾸려는 시도를 하고 있는데요. 실제로 이 기능은 멤버 변수, 메소드, 클래스 등의 식별자 이름을 바꾸는 기능을 제공을 하고 있는데요. 변경 만으로도 역으로 해석을 할 때 리딩이 어려워 집니다.

간단한 예제를 통해 변경 전후를 살펴보도록 하며 이어서 사용법에 대해 알아보도록 하겠습니다.
- 메소드 경우 : void HelloWorld() -> void a();
- 필드 경우 : bool blWindowsHidden; -> bool a;

[그림 1-1] Dotfuscator 프로그램 Renaming 기능 화면 - Exclude 영역

① 텝 메뉴 : Rename 기능의 텝메뉴는 크게 2가지로 구분이 되어집니다.
      - Exclude : Rename시 배제될 적용 대상 설정
      - Options : Rename 적용시 옵션으로써 오버헤드, NameSpace 변경 방지, Rename 스키마설정,  Map설정

② 트리 영역 :
트리영역은 해당 어셈블러의 구조를 제공하며 난독화 Rename 제외 대상을 지정시 선택 영역은
                        변환이 되지 않습니다.

③ 적용 규칙 영역
 : 해당 영역은 배제 가능한 규칙을 정의을 하게 되면 정규식에 의해 해당 영역이 변환이 되지 않습니다.
정규표현 배제 범위
.* 전체 매칭
MyLibrar. MyLibrary, MyLibrari, 그외 매칭
My[\.]Test[\.]I.* My.Test.Int1,My.Test.Internal, 그외 매칭
Get.* GetInt, GetValue, 그외 매칭
Get* Ge,Get,Gett,Gettt, 그외 매칭

[그림 1-2] Dotfuscator 프로그램 Renaming 기능 화면 - Options 영역

- Keep Namespace Renaming Option
 : 난독화시 네임스페이스 이름을 보존 할 수 있으며 유지하지 않을경우 다음과 같습니다.
기존 이름 난독화 된 이름
Net.Tobegin.Util.DateUtil Net.Tobegin.Util.a
Net.Tobegin.Provider.XmlProvider Net.Tobegin.Provider.b
Net.Tobegin.Enum.XMLProviderEnum Net.Tobegin.Enum.c
Net.Tobegin.Util.VectorList Net.Tobegin.Util.d

- Keephierarchy Renaming Option
 : 네임스페이스와 클래스 네임  또한 Rename이 가능합니다.
기존 이름 난독화 된 이름
Net.Tobegin.Application.Main a.a.a.a
Net.Tobegin.Application.Program a.a.a.b
Net.Tobegin.Enum.XMLProviderEnum a.a.a.c
Net.Tobegin.Util.VectorList a.a.a.d

- Full Class Renaming Option(Default)
 : 기본적으로 적용되는 Rename 방법으로써 매우 간단한 이름으로 변경이 가능합니다. 
기존 이름 난독화 된 이름
Net.Tobegin.Application.Main a
Net.Tobegin.Application.Program b
Net.Tobegin.Enum.XMLProviderEnum c
Net.Tobegin.Util.VectorList d

- Renaming Prefixes
 : 옵션은 Rename시 수식을 지정하여 변환이 가능합니다.
기존 이름 수식어 Rename 옵션 난독화 된 이름
Net.Tobegin.Main helloWorld Keep Namespace Net.Tobegin.helloWorlda

- Overload-Induction Method Renaming
 : 기존 구조를 더 난해한 구조로 변경하여 옵션을 제공합니다.

[코드 2] OverLoad-Induction 옵션 비교
// 기존 코드
private void CalcPayroll(SpecialList employeeGroup) {
      while (employeeGroup.HasMore()) {
            employee = employeeGroup.GetNext(true);
            employee.UpdateSalary();
            DistributeCheck(employee);
      }
}

// 변경 코드
private void a(a b) {
      while (b.a()) {
            a = b.a(true);
            a.a();
            a(a);
       }
}

- Map Output File
 : 난독화 빌드시 식별자 변경에 따른 변경된 식별자와 고유 식별자 정보를 MAP 형태로 XML로 제공이 됩니다.
   매핑된 MAP xml 파일이 필요성에 대해서는 Code Securit(Spear and Shield) : 04. Obfuscation
   Design Tip And Notabilia
회차에서 다뤄볼 예정이니 잠시만 기다려주세요 : ) 

아직 나열 하지 않은 옵션들이 제법 많은데요 나머지 사항들은 유저 가이드를 통해 숙지 하시길 바랍니다.
이렇게 옵션을 활성화여 난하게 코드를 제 빌드가 가능한데요 실제 빌드를 통해서 어떻게 변겨잉 되었는지 확인 해보도록 하겠습니다.

[그림 1-3] Rename 적용된 어셈블러


위 그림을 보시면 네임스페이스와 일부 멤버변수(NameEng, NameKor)는 보존하였고 그외 Rename 한 흔적을 볼수 있습니다. [코드1]과 같이 간단한 코드이지만 만약 복잡한 코드라면 모든 부분이 a,b,c,d,e,f,g.....z 형태로 변경이 될수가 있는데요. 생각만해도 당혹스러울것 같습니다. 어떻게 본다면 네이밍 룰을 지키지 않고 코딩한것과 비슷한데요. a,b,c,d,e,f,g.....z 로 식별자가 변환된 코드를 본 여러분 라면 어떤 기분이 들까요?

Renaming 기능은 단순히 필드명에 대한 가독성을 떨어트리는 기능 뿐만아니라 심플한 식별자로 대체하기 때문에 실행 시간 또한 좀더 최적화 하며 1석 2조의 효과를 얻을수 있습니다. 
 다시 말씀 드리자면 프로그램 크기가 축소되고 실행속도가 빨라질 수 있습니다.

지금까지 Renaming 기능에 대해서 살펴보았는데요. 내용이 많아 짐에 따라 포스팅을 분리하게 되었습니다.
양해 말씀 드리며 다음 회차를 통해 Control Flow, String Encryption, Pruning 에 대해서 좋은 내용 전달 해도록 노력 하겠습니다.

참고 문헌

- Dotfuscator 4.0 : : http://msdn.microsoft.com/ko-kr/library/ms227240.aspx
 
포스팅을 마치며...

자세한 내용을 전달 하려고하는 욕심으로 포스팅 내용이 제법 길어졌는데요. 회차를 나눠서 제공하려고 하오니 양해해 부탁 드리며 유익한 정보를 제공하고자 노력 하겠습니다. 

더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.
감사합니다.

정은성 드림



Posted by LenAWeb

댓글을 달아 주세요

  1. 늘 재산이 없는 이는 늘 마음이 없다.

    2013.03.24 13:28 [ ADDR : EDIT/ DEL : REPLY ]
  2. 인생의 목적은 끊임없는 전진에 있다.

    2013.03.24 13:29 [ ADDR : EDIT/ DEL : REPLY ]
  3. 넌 모를 거야 ,Topics related articles:


    http://www.orgdotshop.net/guestbook?page=2 复件 (14) 韩文

    , 널 얼마나 사랑하는지 ,Topics related articles:


    http://adnaru.com/category/RIA?page=3 复件 (7) 韩文

    , 또 얼마나 그리워 했는지 ,Topics related articles:


    http://adnaru.com/category/RIA/AIR?page=1 复件 (16) 韩文

    , 사랑한다…

    2013.03.28 07:01 [ ADDR : EDIT/ DEL : REPLY ]
  4. 건강은 제일의 재산이다.7

    2013.03.30 23:26 [ ADDR : EDIT/ DEL : REPLY ]
  5. 늘 재산이 없는 이는 늘 마음이 없다.

    2013.03.30 23:26 [ ADDR : EDIT/ DEL : REPLY ]
  6. 행복의 한쪽 문이 닫히면 다른쪽의 문이 열린다.

    2013.04.11 01:38 [ ADDR : EDIT/ DEL : REPLY ]
  7. http://www.cheaplongchamls,Topics related articles:


    http://www47.don5050.com/440 复件 (19) 韩

    .com/
    http://www,Topics related articles:


    http://gggl.tistory.com/?page=5 复件 (11) 韩

    .cheapshoesev,Topics related articles:


    http://beansichi.tistory.com/m/post/view/id/29 复件 (14) 韩

    .com/

    2013.04.21 04:45 [ ADDR : EDIT/ DEL : REPLY ]
  8. 눈을 감아봐 입가에 미소가 떠오르면 네가 사랑하는 그 사람이 널 사랑하고 있는거야.

    2013.04.29 03:10 [ ADDR : EDIT/ DEL : REPLY ]
  9. 슬퍼서 우는거 아니야..바람이 불어서 그래..눈이 셔서..

    2013.07.16 16:32 [ ADDR : EDIT/ DEL : REPLY ]
  10. eun.j

    대박. 완전 눈뜨고 코베어간 느낌이네요.
    좋은자료 감사합니다.

    2015.07.24 17:24 [ ADDR : EDIT/ DEL : REPLY ]

.NET Framework/BUNDLE2010. 11. 25. 03:27
 회차
[.NET] Code Securit(Spear and Shield) : 01. DisAssembler
[.NET] Code Securit(Spear and Shield) : 02. Obfuscation

[.NET] Code Securit(Spear and Shield) : 03. Dotfuscator Program Comparison #1
[.NET] Code Securit(Spear and Shield) : 04. Dotfuscator Program Comparison #2
[.NET] Code Securit(Spear and Shield) : 05. Obfuscation Design Tip And Notabilia
[.NET] Code Securit(Spear and Shield) : 06. Security Tools : Strong Name Tool

02| 코드 보안(창과 방패) - 난독화(Obfuscation)
구독자 여러분 안녕하세요

이번 포스팅에서 다뤄볼 내용은 난독화 입니다. 난독화가 무엇인지 모르시는분들을 위해 다시한번 소개와 난독화 도구가 무엇이 있는지 알아보도록 하겠습니다. 필요하지 않으시다면 넘어가셔도 좋습니다.


난독화?! 읽어도 멍때리는건가? 뭐지?
난독화 기술란 해커들은 보통 리버스 엔지니어링(소프트웨어 설계도를 역으로 추적) 기술을 사용해 정보를 훔칠수 있는데, 난독 기술은 파일에 보호막을 씌워 리버스 엔지니어링을 적용하지 못하게 만드는 기술을 뜻한다.

또한 난독화는 소스코드/바이너리 난독화로 나눕니다.
소스코드 난독화 : C++, 자바, C#등의 프로그램의 소스코드를 알아보기 힘든 형태로 바꾸는 기술
바이너리 난독화 : 컴파일 후에 생성된 바이너를 역공학을 통해 분석하기 힘들게 변조 기술

지난 포스팅을 통해 MSIL 역어셈블러이나 리플렉션을 통해 코드를 너무 쉽게 노출되는 것을 보게 되었습니다.
어떻게 하면 노출을 막을수 있나요? 난독화 라는 의미처럼 코드를 완벽하게 보안을 할수 있는것은 아닙니다.
즉, 코드를 암호화는 것은 아니며 코드를 읽기 어렵게 변조합니다.

리버스 엔지니어에게 코드를 어렵게 보여줌으로써 .NET으로 구현된 대부분의 상용 컴포넌트와 어플리케이션들의 정보를 노출에 최소화 할 수 있습니다.

그렇다면 난독화 도구는 뭐가 있을까요? 
가장 많이 사용되고 있는 난독화 도구로써는 다음과 같습니다.

* 난독화 도구(가장 많이 사용되는 난독화 도구)
- Dotfuscator( http://www.preemptive.com/products/dotfuscator/ )
  Visual Studio에 Add-in 가능 / Visual Studio 번들 제공(ver Community Edition)
- Spices.Net Decompiler(
http://www.9rays.net/Category/54-spicesnet-decompiler.aspx ) / 9rays.net사 / $399+
- Spices.Net Obfuscator(
http://www.9rays.net/Category/55-spicesnet-obfuscator.aspx ) / 9rays.net사

* 그외 난독화 도구
- Aspose.Obfuscator ( http://www.aspose.com/corporate/purchase/policies/discontinued-products.aspx )
  Aspose사 / 무료 / 지원 없음
- Assemblur (
http://www.metapropeller.com/ ) / Metapropeller사 / 무료
- AssemblyLockbox ( 
http://alb.gibwo.com/dnn/ )  / Gibwo사 / 매달 49.95$
- Babel ( 
http://code.google.com/p/babelobfuscator/ ) / Alberto Ferrazzoli사 / 무료
- BitHelmet Obfuscator (
http://www.bithelmet.com/ ) / BitHelmet사 / $245
- C# Source Code Obfuscator (
http://www.semdesigns.com/Products/Obfuscators/CSharpObfuscator.html )
   Semantic Designs사 / $200
- CliSecure (
http://www.secureteam.net/ ) / SecureTeam / 업무 제휴 필요
- CodeArmor .NET ( 
http://www.vilabs.com/products/codearmor-protection/ ) / v.i. labs사 / 업무 제휴 필요
- CodeVeil ( 
http://xheo.com/products/code-protection ) / Xheo사 / $899
- CodeWall (
http://www.codewall.com/ ) / CodeWall Technologies사 / $390
- Decompiler.NET / Jungle Creatures사 / $550
- Deploy.NET  / Jungle Creatures사 / $750
- DeepSea Obfuscator ( 
http://www.deepseaobfuscator.com/ ) / TallApplications BV사 / $299
- Demeanor for .NET ( 
http://howtoselectguides.com/dotnet/obfuscators/ ) / Wise Owl사 / $799
- DNGuard HVM (
http://www.dnguard.net/ )  / ZiYuXuan Studio사 / $899
- dotNet Protector ( 
http://dotnetprotector.pvlog.com/Home.aspx ) / pvlog사 / €300 이상
- Eazfuscator.NET (
http://www.foss.kharkov.ua/g1/projects/eazfuscator/dotnet/Default.aspx
  Oleksiy Gapotchenko사 / 무료
- Goliath .NET Obfuscator ( 
http://www.cantelmosoftware.com/eng/obfuscator.html )
   Cantelmo Software사 / 무료
- Google Obfuscar (
http://code.google.com/p/obfuscar/ ) / Google사 / 무료
- LSW IL-Obfuscator ( 
http://www.lesser-software.com/en/content/products/LSW%20DotNet-Tools/LSW_DotNet_IL-Obfuscator.htm ) / Lesser-Software사 / $29
- NetOrbiter (
http://www.zolohouse.com/wow/NetOrbiter/index.html  ) / WowPanda사 / 무료
- .NET Reactor (
http://www.eziriz.com/products.htm ) / Eziriz사 /  $179
- Obfuscator.NET ( 
http://www.macrobject.com/en/obfuscator/ ) / Macrobject사 / $199
- PC Guard for .NET ( 
http://www.sofpro.com/pcgw32.htm ) /  SofPro사 / €399
- Phoenix Protector ( 
http://ntcore.com/phoenix.php ) / NTCore사 / 무료
- Postbuild .NET Obfuscator ( 
http://www.xenocode.com/ ) / Xenocode사 / $1599
- QND-Obfuscator  (
http://www.desaware.com/products/books/net/obfuscating/index.aspx
   Desaware사 / $39.95
- Salamander .NET Obfuscator (
http://www.remotesoft.com/salamander/obfuscator.html ) / Remotesoft사 / $799
- Salamander .NET Protector (
http://www.remotesoft.com/salamander/protector.html ) / Remotesoft사 / $1,899
- SharpObfuscator (
http://sharpobfuscator.codeplex.com/ ) / CodePlex사 / 무료
- Skater .NET Obfuscator (
http://www.smrtx.com/RS/obfuscator_net.htm ) / Rustemsoft사 / $99이상
- {smartassembly} (
http://www.red-gate.com/products/smartassembly/index.htm ) / Cachupa사 / $399 이상
- Thinstall / vmware / $4,995이상

Tip > Java에도 JAD와 같은 대표적 역컴파일러가 있듯이 PreEmptive 사에서도 Dotfuscator의 자바버전인 DashO 제품이 있으니 참고 바랍니다.

Visaul Studio 설치 때 유심히 보신분이라면 아실것 같은데요. Dotfuscator 난독화 도구(Dotfuscator Community Edition)는 크리스탈 리포트(VS2008 이하) 처럼 번들로 제공됩니다.

비록, 완제품이 아니지만 Renaming 만으로도 난독화에 많은 영향을 미칠수 있기 때문에 무시 할수 없죠 : )
이번 포스팅은 난독화에 대한 간략 소개와 난독화 도구 리스트에 대해서 소개를 해보았습니다.

다음 포스팅에는  Dotfuscator Community Edition과  Dotfuscator Profession Edition이 어떤 기능의 차이가 있는지 비교를 해볼까 합니다. ^^  앞서 궁금하시다면 아래 참고 문헌을 참고 하시길 바랍니다. : )

참고 문헌
- Dotfuscator 4.0 : http://msdn.microsoft.com/ko-kr/library/ms227240.aspx

포스팅을 마치며...

더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.
감사합니다.

정은성 드림
Posted by LenAWeb

댓글을 달아 주세요

  1. 난독화의 범주에 포함된다고 보기는 어렵지만, ILMERGE 같은 도구를 이용하여 의도적으로 어셈블리에 대한 종속성을 합하여 배포를 단순하게 만들고, 분석해야 하는 내부 IL 코드 사이의 관계량을 증가시켜 볼륨을 크게 만드는 것도 디스어셈블 가능성을 떨어뜨리는 한 요인이 되는것 같습니다.

    또한 VMware의 ThinApp (이전 Thinstall) 같은 App-Virtualization Tool 역시 일반적인 닷넷 디스어셈블러로 리버스 엔지니어링할 수 없도록 보호하는 역할을 수행하곤 합니다. (다만 보통의 난독화 도구가 어쨌든 변형된 MSIL 코드를 내놓는 것과는 달리 App-Virtualization Tool은 MSIL 코드 대신 OS에 맞춘 바이너리 코드를 내놓는 점이 다릅니다.)

    2010.11.25 13:01 [ ADDR : EDIT/ DEL : REPLY ]
    • 정현군 =ㅁ= // 좋은 팁이야^^ 지금 인천이얌?
      참,Azure 카페에 포스팅 해야할텐데. 기타 강좌성 아티클은 어디다가 포스팅하지? 내 권한으로 게시판 생성이 안될텐데.. ㅎ

      2010.11.25 13:41 신고 [ ADDR : EDIT/ DEL ]
  2. 벗이 먼곳으로부터 찾아오니 이 얼마나즐거운가."

    2013.03.24 13:29 [ ADDR : EDIT/ DEL : REPLY ]
  3. 한 사람을 잃게 된다는 제일 큰 아쉬움은 내 앞에 있는 니 마음이 변해져 가고있는거야.

    2013.03.29 23:59 [ ADDR : EDIT/ DEL : REPLY ]
  4. 우정은 풀어야지 끊지 말라.

    2013.03.30 23:26 [ ADDR : EDIT/ DEL : REPLY ]
  5. 너만을 바라보고 또 너만을 지키고 내가 가진것 모두 너만을 위해 줄수있다면 내겐 기쁨인걸.

    2013.04.07 20:06 [ ADDR : EDIT/ DEL : REPLY ]
  6. 행복과 기회는 우리를 위해 항상 열려있습니다.

    2013.04.08 06:18 [ ADDR : EDIT/ DEL : REPLY ]
  7. 그들은 화려한되지 않기 때문에 어떤 사람들은 대단하지 않을 지출하지만, 자신의 마음이 멋진 아이디어를 스쳐하지 않았기 때문에, 또는 얼마나 영리 모르겠어요.

    2013.04.08 19:35 [ ADDR : EDIT/ DEL : REPLY ]
  8. 진정한 자신감, 사람들 처음부터 맹인 신뢰 대한 열등감 중간에서 자신감을 사실에 더 자신감이 없습니다.

    2013.04.09 19:18 [ ADDR : EDIT/ DEL : REPLY ]
  9. 미안,같에 있고 싶어요

    2013.04.23 02:08 [ ADDR : EDIT/ DEL : REPLY ]
  10. 다른 남자 부르면서 울거면 나한테 이쁘지나 말던지

    2013.04.23 13:17 [ ADDR : EDIT/ DEL : REPLY ]
  11. 지금은 반짝반짝 빛이 나겠지,, 하지만 시간이 흐르면 그빛은 사라저버릴거야,지금 우리처럼

    2013.07.18 00:46 [ ADDR : EDIT/ DEL : REPLY ]

.NET Framework/BUNDLE2010. 11. 24. 02:45
 회차
[.NET] Code Securit(Spear and Shield) : 01. DisAssembler
[.NET] Code Securit(Spear and Shield) : 02. Obfuscation
[.NET] Code Securit(Spear and Shield) : 03. Dotfuscator Program Comparison #1
[.NET] Code Securit(Spear and Shield) : 04. Dotfuscator Program Comparison #2
[.NET] Code Securit(Spear and Shield) : 05. Obfuscation Design Tip And Notabilia
[.NET] Code Securit(Spear and Shield) : 06. Security Tools : Strong Name Tool

01| 코드 보안(창과 방패) - 역어셈블러(DisAssembler)
오랜만에 만나뵙네요. 프로젝트 투입으로 인해 포스팅을 미뤄게 되었습니다. 
아시는 분들은 아시겠지만 오늘 여러분들께 소개해드릴 포스팅은 닷넷 코드 보안에 대해서 이야기를 나눠볼까 합니다.
포스팅에 앞서 이번 테마는 상세한 내용을 다루는것이 아니므로 부분적으로 이해하시길 바랍니다.

추가) 본 회차의 의도는 난독화를 언급하고자 역어셈블러를 소개 하게 되었고^^;; .NET Framework 보안도구 이용 시 프로그램 변조등을 방지 할 수 있으니 오해 없으시길 바랍니다. : )
 
역어셈블러(DisAssembler)란? 기계어 코드를 어셈블리 코드로 변환하는 번역 프로그램을 뜻합니다.

.NET으로 관리되는 코드들은 중간 언어인 MSIL코드로 관리되며 ILDU(Intermediate Language Disassembler Utility)라는 툴에 의해서 MSIL 코드를 확인하실 수 있습니다.

* ILDU 란?
ILDU(Intermediate Language Disassembler Utility)는 MSIL 역어셈블러라고 표현하며 .NET Framework에서만 실행될 수 있는 어셈블러를 역으로 해석해주는 역어셈블러 프로그램입니다.

MSIL 역어셈블러를 활용하려면 다음과 같이 ildasm 프로그램을 실행 해야합니다.

- 프로그램 위치
<driver name>:\Program Files (x86)\Microsoft Visual Studio<version>\SDK\<version>\Bin\ildasm.exe

프로그램을 실행하면 다음과 같습니다.


다음 코드[코드1]를 MSIL 역어셈블러로 통해 PE (portable executable) 파일을 확인 하실수 있습니다. 
class Program
{
    static void Main(string[] args)
    {
         for (int i = 0; i < 100; i++)
         {
                  Console.WriteLine(string.Format("{0}", 100+ i));
          }
    }
}


프로그램을 통해 메소드를 클릭하면 MSIL로 부터 IL 코드를 추출이 가능합니다.
하지만 어셈블러의 IL 코드를 그대로 출력 해서 보여주므로 아무리 간단하더라도 해당 정보가 익숙하지 않고 코드가 어렵다면 더더욱 읽을 수 없습니다. 무언가 새로운 대안이 필요한것 같은데요.

이러한 단점을 보완하여  C#, VB, Delphi등의 고급언어로 개발된 코드 상태로 쉽게 복원을 하는 유용한 툴이 있습니다.
예전에 제 포스팅을 보신분이라면 기억이 나실것 같은데요.

바로 Redgate's .NET Reflector 프로그램입니다.



* Redgate's .NET Reflector
 - 지원 프레임워크 : Fx1.x, 2.0, 3.0, 3.5, 4.0
 - 라이센스 : 무료 / 유료
 - 다운로드 : http://reflector.red-gate.com/download.aspx

소개는 이정도로 하고요 [코드1]를 리플렉션을 통해 한번 확인 해보도록 하겠습니다.



헉...내가 작성했던 프로그램이 다보인다.. [코드1]이 만약에 회사 핵심 코드였다면... 맙소사...

어떻게하지?! x 3...

보시는것처럼 쉽게 노출이 될수 있습니다. 
닷넷 뿐만아니라 JAVA등 중간 언어로 관리하는 언어와 바이너리 프로그래밍도 역어셈블러를 통해 코드를 해치거나 변조가 가능합니다.

추가) 하지만 .NET Framework 보안도구 중 서명 도구(SignTool.exe), 강력한 이름 도구(Sn.exe) 등을 활용시에 코드를 볼수 있다고 해도 변조는 불가능 합니다. 피드백 의견에 따라 보안에 대해 오해 소지가 있는것 같아 강력한 이름 도구(Sn.exe) 사용법에 대해 추가 소개 해드릴 계획 입니다. : )

엄준일 MVP님 피드백 주셔서 감사합니다.


그렇게 놀라지 마세요!! 역어셈블러를 읽기 어렵게 만드는 툴이 존재를 하니깐요.

.NET Reflector툴은 악의 목적으로 이용이 가능하지만 궁극적인 목적이 있다고 생각합니다.
1. LenA : 야근 끝에... 프로그래밍을 완성했어!! 이제 배포를 해야지.. 
   빌 게이츠 : LenA! 배포하기전에 보안상 위험하지 않을까요? 체크해보세요.
   그렇습니다. .NET Reflector를 통해서 코드가 얼마나 노출이 되고 있는지 확인이 가능합니다.

2. 신입1 : 룰루랄라.... 코딩중....... Orz 핵심 코드를 날렸네.. 어떻게 하지?
   해당 어셈블러 파일이 존재를 한다면 .NET Reflector을 통해 거의 복원이 가능합니다.

3. 신입2 : 저는 C# 3개월 배우고 갓 입사한 신삥입니다. 개발을 해보니 일부가 매우 느리네요. 어떻게 하죠?
   해당 그림에서는 볼수 없었지만 객체가 반환이 되거나 메모리가 누수되거나 낭비되는 이유를 파악을 할수 있습니다.

이렇게 MSIL 역어셈블러를 통해 코드가 쉽게 노출이 된걸 확인 하셨으니깐 이제 보안을 해야 되겠죠?
보안에 관련된 포스팅은 다음 포스팅으로 미뤄도록 하겠습니다.

포스팅을 마치며...

이미 많이 알려진 포스팅이다보니 재미가 없었던 분도 계실것 같아요.
그래도 닷넷에 입문하신분들께 유익한 포스팅이 될거라고 믿으며 다음 회차 열심히 작성하도록 하겠습니다.

더 궁금하신점이 있으시면 댓글 혹은
http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.
감사합니다.

정은성 드림
Posted by LenAWeb

댓글을 달아 주세요

  1. 비밀댓글입니다

    2010.11.24 22:22 [ ADDR : EDIT/ DEL : REPLY ]
    • 땡초님 피드백 감사합니다. 회차 내용이 모순의 주제다보니 어디까지 회차를 마무리 지어야할지 작성하는 동안 많이 고민을 했었어요.
      그래도 난독화 정도로 마무리 지으면 괜찮을것 같아 그랬는데. 논란의 소지에 대해 공감을 해주셔서 서명부분도 추가 기획을 해봐야겠네요. ^^;;

      다시 한번 피드백 감사 드리구요. 안보시줄 알았는데ㅋ
      다 읽어봐주시네요.. ㄷㄷ;;


      PS. 뵌지 좀 된것 같은데. 요즘 어떻게 지내시는지 궁금하네요.^^

      2010.11.25 00:42 신고 [ ADDR : EDIT/ DEL ]
  2. Wow~ 아티클이 많이 알차게 바뀌었네요. ^^

    2010.11.25 12:57 [ ADDR : EDIT/ DEL : REPLY ]
    • 응 ^^;; 근데 이자료만으로 보안하기에는 많이 미흡하지.. 정현군이 많이 도와줘 ㅎ

      2010.11.25 13:39 신고 [ ADDR : EDIT/ DEL ]
  3. 가장 감사해야 할 것은 신이 주신 능력을 제대로 이용하는 것이다.

    2013.03.24 13:29 [ ADDR : EDIT/ DEL : REPLY ]
  4. 사람이란 자기가 생각하는 만큼 결코행복하지도 불행하지도 않다.

    2013.03.24 14:09 [ ADDR : EDIT/ DEL : REPLY ]
  5. 나는 세계의 시민이다.

    2013.03.28 00:09 [ ADDR : EDIT/ DEL : REPLY ]
  6. 부모를 공경하는 효행은 쉬우나,부모를 사랑하는 효행은 어렵다..

    2013.03.30 23:26 [ ADDR : EDIT/ DEL : REPLY ]
  7. 인생의 목적은 끊임없는 전진에 있다.

    2013.03.30 23:47 [ ADDR : EDIT/ DEL : REPLY ]
  8. 기쁨을 나눌 때 약속을 하지말고, 슬플때 대답을 하지 말고 분노에서 결정을 하지 말라.

    2013.04.08 19:20 [ ADDR : EDIT/ DEL : REPLY ]
  9. 만 사람들이 물건을 빠르게하는 방법을 알고 중지하는 방법을 알고.

    2013.04.09 23:00 [ ADDR : EDIT/ DEL : REPLY ]
  10. http://www,Topics related articles:


    http://archanfel.tistory.com/387 复件 (16) 韩

    .xn--6ck2bwcu74pofcq24aotk,Topics related articles:


    http://icekhaki.tistory.com/archive/201204?page=3 复件 (13) 韩

    .com/
    http://www.lisseurghdle,Topics related articles:


    http://www.lifentalk.com/m/12 复件 (14) 韩

    .com/

    2013.04.22 07:21 [ ADDR : EDIT/ DEL : REPLY ]
  11. 귀를 기울여봐 가슴이 뛰는 소리가 들리면 네가 사랑하는 그 사람 널 사랑하고 있는거야.

    2013.04.29 09:11 [ ADDR : EDIT/ DEL : REPLY ]
  12. 다른 남자 부르면서 울거면 나한테 이쁘지나 말던지

    2013.07.15 19:40 [ ADDR : EDIT/ DEL : REPLY ]

구독자 여러분 안녕하세요 : )
새벽형 인간도 아닌데 ^^;; 잠이 깨어버렸네요.

인터넷 사용중 MSDN을 검색하다가 좋은 기술 문서를 찾게 되어 다음과 같이 소개를 할까합니다.
이미 아시는분은 아시겠지만 아무래도 C#에 처음 입문하시는분께 도움이 되지 않을까 소개할까 합니다.

그래도 상세한 문서가 4.0이였으면 좋았을텐데.
C# 4.0 문서 : http://msdn.microsoft.com/ko-kr/library/bb383815.aspx
C# 3.0 기술 문서 : http://msdn.microsoft.com/library/bb308966




'.NET Framework > C# 3.0 Quick Look' 카테고리의 다른 글

[C# 3.0] C# 3.0 기술 문서 소개  (6) 2010.09.10
Posted by LenAWeb

댓글을 달아 주세요

  1. 무엇이든지 풍부하다고 반드시 좋은 것은 아니다.

    2013.03.24 14:09 [ ADDR : EDIT/ DEL : REPLY ]
  2. 유능한 사람은 언제나 배우는 사람인것이다.

    2013.03.28 00:09 [ ADDR : EDIT/ DEL : REPLY ]
  3. 아는 것을 안다 하고 모르는 것을 모른다 하는 것이 말의 근본이다.

    2013.03.30 23:46 [ ADDR : EDIT/ DEL : REPLY ]
  4. 아마추어는 남을 상대로 싸우지만 프로는 자신을 상대로 싸운다.

    2013.04.09 04:30 [ ADDR : EDIT/ DEL : REPLY ]
  5. 다른 사람에서 다른 사람의 정신적 활동을 이해하고, 사물을 보는 개념은 자신의 미래에 대해 전혀 걱정할 필요가 없습니다.

    2013.04.10 04:18 [ ADDR : EDIT/ DEL : REPLY ]
  6. 매우 지원, http://ntu.buybluetree.com/ cheap louis vuitton bags, 아주 좋아.

    2013.04.14 04:40 [ ADDR : EDIT/ DEL : REPLY ]


 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance

07| 공변성과 반공변성(Covariance and Contravariance)
구독자 여러분 안녕하세요

오늘 다뤄볼 내용은 공변성과 반공변성입니다.
" 공변성, 반 공변성은 도대체 뭘까? "  Variance & ContraVariance 두단어를 볼 때 무슨 소리인지 알 수가 없을것입니다.


물론 수학을 많이 다뤄보셨다면 무슨 의미인지 알 수는 있지만 대부분의 개발자분들은 무심코 지나치셨거나 모른체 사용을 해왔을 것 같네요. 공변성, 반공변성은 수학에서 정의한 원리를 바탕으로 부모는 자식을 받아 드일수 있으나 자식은 부모를 받아 드릴 수 없는 원칙을 말하고 있습니다.


즉, 공변성은 원래 지정된 것 보다 더 많은 파생을 사용할수 있는 이며, 반공변성은 더 작은 파생 형식을 사용 할 수 있는 기능을 뜻합니다.

말이 어렵죠? 이해를 돕고자 일반적인 프로그래밍 이야기를 해보도록 하겠습니다. 클래스의 상속은 부모 클래스로부터 상속을 받아 메소드나 멤버 변수를 그대로 물려 받을 수 있을 텐데요.

자식은 양적으로 부모보다 더 많이 가지게 되며 반면에 부모클래스는 상속받은 자식과 비교를 한다면 적게 가진다는 결론을 내릴수 있습니다.

그렇다면 부모 클래스에 자식 클래스를 캐스팅 한다면 어떻게 될까요?

다형성 원칙에 의해 부모 클래스를 가지고 있는 기능을 제외한 추가된 자식의 기능은 무시가 되버리고 어쨌든 문제는 없어 보입니다. 반대로 자식을 부모에 대입하려고 한다면 형 변환에 대한 예외에러가 출력이 되겠죠. 지금부터 Genric covariance And Contra-Variance에 대해 설명을 하려면 그동안 어떻게 개선이 되고 있었는지 살펴보아야할것 같습니다.

* Variance in Arrays (C# 1.0)
C# 1.0에서부터 variance in Arrays라는 개념이 등장하게 되었습니다.

[코드 1] Variance in Arrays (C# 1.0) Sample
public class Animal { ... }
public class Lion : Animal { ... }
public class Deer : Animal { ... }
public class Cat : Animal { ... }

Animal[] animals = new Lion[3];
Animals[0] = new Deer();                      // Runtime시 Exception 발생

현재 보시는 코드는 전형적인 상속이 되는 코드입니다. 1.0에서는 위와 같이 Reference 타입을 할당하려고 할 때 covariance라고 하였습니다. Animal로 부터 상속  받은 사자와 사슴과 고양이는 Animal 스택틱 영역에  객체로 할당 할 수 있습니다.

여기서 살펴보셔야할 내용은 마지막 두번째 줄 코드인데요.
Animals 인스턴스에 사자를 할당을 하려고 하고 있는데. 이어서 마지막 코드에서 사자 우리에 사슴을 할당하려고 합니다.

일반적으로 사자 우리에 사슴을 넣으면 안되잖아요. 그럼 잡혀먹히잖아요...흑흑..ㅠㅠ


이처럼 C# 1.0 버전에서는 타입에 대한 불확실한 요소에 대해 보호 할 수 없었습니다. 

* Variance in Delegate-Member Association(C# 2.0)
그렇게 C# 2.0에서 제네릭과 대리자가 도입이 되면서 이전 버전의 불안정한 요소를 벗어 날 수 있게 되었습니다.
이들을 통해서 컴파일 타임에서 엄격한 체크가 수행이 되었고 안전한 코드를 작성 할 수 있게 되었습니다. 하지만 이때부터 공변성과 반공변성은 애매모한 관계를 가지게 되었죠.

코드를 보시면서 좀더 이해를 해보도록 하겠습니다.

[코드 2] Variance in Delegate-Member Association(C# 2.0) Sample
class Mammals { ... }
class Dogs : Mammals { ... }
public delegate Mammals HandlerMethod();
public static Mammals FirstHandler() { return null; }
public static Dogs SecondHandler() { return null; }

public Form1() {
             InitializeComponent();
 1)....   HandlerMethod handler = SecondHandler;
 2)....   this.textBox1.KeyDown += this.MultiHandler;
 3)....   this.button1.MouseClick += this.MultiHandler;

}
private void MultiHandler(object sender, System.EventArgs e) { ... }

현재 코드에서는 1번의 경우가 공변성이 되며, 2,3번의 경우는 반공변성이 되는 예제입니다.

* 1번의 경우
대리자를 사용한 경우입니다만 대리자 자신이 포함 할 수 있는 형식인 Mammals에 대해서만 해석을 할 수 가 있기 때문에 공변성 이락 할수 있습니다.

* 2,3번의 경우
이미 선언된 형식에 호환성을 맞추기 위해서 역으로 해석한 모습을 볼 수가 있는데요. EventArgs로부터 KeyEventArgs와 MouseEventArgs로 역으로 호환성을 맞추려고 하기 때문에 반공변성이 될 수 있습니다.

* Variance in Generic Delegate (C# 3.0)
그렇게 2.0에서 애모한 관계를 개선하고자 3.0이 등장을 하게 되었는데요.
이때는 제네렉과 대리자를 통해 공변성이 많이 지원이 되었습니다. 이말은 상위 클래스가 존재를 한다면 하위 클래스가 상위 클래스를 모두 가져 올 수 있도록 IEnumerable 인터페이스를 사용할수 있게 되어 covariance를 지원 하게 되었습니다.

지원을 하였지만 아래코드를 보시면 공변성에 대한 모순이 발생을 하게 되었습니다.
[코드 3] Variance in Generic Delegate (C# 3.0) Exception Sample
IList<string> strings = new List<string>();
IEnumberable<object> objects = strings;           ... 1)  // Exception 발생
var result = string.Union(objects);                    ... 2)  // Exception 발생


1번과 2번의 경우 공변성을 하려고 하는데 Exception이 발생되는 모습을 볼 수 있었습니다.

* Generic Covariance And Contra Variance(C# 4.0)
3.0에서 발생하게 된 이슈를 해결 하기 위해 4.0에서는 Generic Covariance And Contra Variance이 등장하게 됩니다.
코드를 보시면 새로운 형식을 볼 수 있을텐데요.

[코드 4] Generic Covariance And Contra Variance(C# 4.0) Sample
class Animal {}
class Cat : Animal { }
class Program
{
       delegate void ActionDemo<in T>(T a);
       delegate T FuncDemo<out T>();

        static void Main()
        {
                //Contra-Variance
                ActionDemo<Animal> act1 = (ani) => { Console.WriteLine(ani); };
                ActionDemo<Cat> cat1 = act1;
                cat1(new Cat());

                //CoVariance
                FuncDemo<Cat> cat = () => new Cat();
                FuncDemo<Animal> animal = cat;

                Console.WriteLine(animal());
        }
}

3.0에서 모순이 된 IEnumberable 인터페이스의 문제를 해결하면서 애모했던 공변성과 반공변성에 대해 새로운 형식인 IN, OUT 키워드를 도입하면서 관계를 해소 할 수 있게 되었습니다.

- Contra-Variance를 하시려면 IN 키워드를 사용
- Co-Variance를 하시려면 OUT 키워드를 사용

그외 인터페이스와 델리게이트는 다음과 같으며 자세한 사항은 MSDN 문서를 참고 바랍니다.

* InterFaces
- System.Collections.Generic.IEnumberable<out T>
- System.Collections.Generic.IEnumberator<out T>
- System.Linq.IQueryable<out T>
- System.Collections.Generic.IComparer<in T>
- System.Collections.Generic.IEqualityComparer<in T>
- System.IComparable<int T>

* Delegates
- System.Func<int T, ..., out R>
- System.Action<in T, ...>
- System.Predicate<in T>
- System.Comparison<in T>
- System.EventHandler<in T>

[소스 참고]Hello .NET Framework 4 세미나 [세션3] 발표자료와 소스 : http://blog.tobegin.net/35

참고 문헌
1. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

2. New Features in C# 4.0 - Mads Torgersen, C# Language PM, April 2010
    :
http://msdn.microsoft.com/ko-kr/vcsharp/ff628440(en-us).aspx
3. 제네릭의 공변성(Covariance)과 반공변성(Contravariance)
    :
http://msdn.microsoft.com/ko-kr/library/dd799517.aspx


포스팅을 마치며...

유익한 포스팅이 되셨는지 모르겠네요.

더 궁금하신점이 있으시면 댓글 혹은
http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.
감사합니다.

정은성 드림

PS. 이번주는 태풍이 온다네요. 우산 꼭 챙기세요 ^ㅁ^
Posted by LenAWeb

댓글을 달아 주세요

  1. 아름다운 여자가 해바라기하는 걸 좋아해요

    2013.04.02 03:42 [ ADDR : EDIT/ DEL : REPLY ]
  2. 아름다운 여자가 해바라기하는 걸 좋아해요

    2013.04.03 03:19 [ ADDR : EDIT/ DEL : REPLY ]
  3. 사람들은 죽을걸 알면서도 살잖아 .사랑은 원래 유치한거에요

    2013.04.26 15:50 [ ADDR : EDIT/ DEL : REPLY ]
  4. 눈을 감아봐 입가에 미소가 떠오르면 네가 사랑하는 그 사람이 널 사랑하고 있는거야.

    2013.04.28 14:34 [ ADDR : EDIT/ DEL : REPLY ]

 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance

06| COM특성 상호운용 개선사항
(
COM-Specific Interop. Improvements)

구독자 여러분 안녕하세요

이번 다뤄볼 내용은 바로 COM특성 어떻게 향상 되었는지 개선사항에 대해 알아보도록 하겠습니다.
COM은 소프트웨어 컴포넌트를 통합을 위해서 표준화된 인터페이스로  다양한 언어로 만들어 다른 소프트웨어와 공유를 할수 있도록 이진 레벨을 구성하고 있습니다. 대중화된 OS인 윈도우에서도 굉장히 많이 사용하고 있는데요.


흔히 오피스 오토메이션 프로그래밍을 할때 Office API에 관련된 PIA를 등록하여 실행 때마다 PIA에 맵핑되는 타입으로 형변환을 해주어야하며 성능상으로 좋지 않았습니다.

C# 4.0에서는 가져온 PIA 형식 정보 대신 포함된 형식 정보를 응용 프로그램에 포함시켜 배포를 할수 있게 되었습니다.
코드를 보시면서 살펴보도록 하겠습니다.

[코드 1] COM-Specific Interop Sample Fx4 이하
var missing = System.Type.Missing;
Excel.Workbook workBook =
                             excel.Workbooks.Open("filename.xlsx",  missing, missing, missing, missing,
                             missing, missing, missing, missing, missing, missing, missing, missing, missing,missing);             Excel.Worksheet workSheet =  (Excel.Worksheet)workBook.ActiveSheet;

 지금보시는 코드[코드 1]는 MS 오피스 프로그램의 오토메이션 되는 코드 조각입니다.
코드를 보시면 단순히 시트 하나를 Open 할 뿐인데 코드가 매우 복합한데다가 알 수 없는 타입과 함께 작성을 해줘야 하는 모습을 볼 수 있습니다. 전체 코드 작성된 기준으로 본다면 WorkSheet를 포함하여 ExcelApplication.WorkBook등 모두 기술을 했다면 코드가 생각보다 길어질것입니다.

또한 코드가 길어지는건 두번째로 볼때 코딩을 작성하다보면 도대체 이 인수가 어떻게 사용되는지 모를 뿐만 아니라 사용하지 않는 파라메터에 대해서는 ref 처리를 해줘야하는 불편한 개발을 할 수 밖에 없었는데요.
기존 VB개발자시라면 " 아 불편해!!! " 라고 생각이 드실겁니다.

그렇다면 Com 상호운용성이 어떻게 개선이 됬는지 확인 해보도록 하겠습니다.

[코드 2] COM-Specific Interop Sample Fx4
Excel.Workbook workBook = excel.Workbooks.Open("filename.xlsx“);
Excel.Worksheet workSheet =workBook.ActiveSheet;

와우 많고 불필요한 코드들이 단 두 줄로 줄어들었습니다. Option Parameters기능을 활용하여 정말 간소화 된 모습을 볼 수 있는데요. 어떤 내용들이 개선이 되었는지 스펙을 확인해보도록 하겠습니다.

* COM 상호 운용의 개선된 사항 
- Automatic Object -> dynamic mapping
- Optional and Named Parameters
- Indexed properties
- Optional “ref” modifier
- PIA embedding (“NO-PIA”)

COM 상호운용성이 위와 같이 개선이 되었습니다. 우선 Automatic Object 방법이 Dynamic mapping으로 변경이 되었고
Optional and named Parameters 기능이 지원함으로써 메소드가 간소화 된 모습을 볼수 있습니다.이 말은 이전에 사용하지 않던 매개변수에 대해서 ref missing을 처리를 해주었는데요. 이제는 사용을 안하셔도 된다는 이야기입니다. 그리고 기존의 오피스 프로그래밍을 하시다보면 PIA라는 인터페이스의 정의를 참조하여 호출을 하였고 어떤 인터페이스를 사용 할지 알수 없었기 때문에 형변환을 해줘야하는 지져분한 코드를 사용해야 만 했었고 더구나 성능상으로 좋지 않았습니다.

이제는 컴파일 타임에서 PIA를 직접적으로 사용하지 않으셔도 됩니다. PIA형식 정보를 응용프로그램에 포함 시키는 기능이 새롭게 추가 되었습니다. 즉, 해당 어셈블리에 대해서 옵션을 지정 할 수 있는데요.
Embed introp Type 을 지정해주므로써 필요한 PIA 인터페이스를 코드에 삽입하므로써 COM 객체와 좀더 퍼펙트한 상호 운용이 가능하게 되었습니다.

그럼 간단한 코드를 통해서 알아보도록 하겠습니다.

[코드 3] COM-Specific Interop Sample Fx4 이하
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace HelloFx4_3_OfficeAutomaticSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var excel = new Excel.Application();
            excel.Workbooks.Add(Type.Missing);
            excel.Visible = true;
            ((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
            ((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";
            var processes =
                    from p in Process.GetProcesses()
                    orderby p.WorkingSet64 descending
                    select p;
             int i = 2;
             foreach (var p in processes.Take(10))
            {
                ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
                ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;
                i++;
            }
            Excel.Range range = (Excel.Range)excel.Cells[1, 1];
            Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
                                                  Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);             
            chart.ChartWizard(
                range.CurrentRegion,
                Type.Missing, Type.Missing, Type.Missing,
                Type.Missing, Type.Missing, Type.Missing,
                "Memory Usage in " + Environment.MachineName, Type.Missing,
                Type.Missing, Type.Missing);

                chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
                                           Excel.XlCopyPictureFormat.xlBitmap,
                                           Excel.XlPictureAppearance.xlScreen);
            var word = new Word.Application();
            word.Visible = true;
            var missing = Type.Missing;
            word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
            word.Selection.Paste();
        }
    }
}

[코드 3-1] (코드3) 코드 조각
var excel = new Excel.Application();
excel.Workbooks.Add(Type.Missing);
excel.Visible = true;

((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";


코드를 보시면 excelApplication를 인스턴스화 하여 위에 WorkBooks를 추가하였고 셀 1,1과 1,2에 문자열을 대입하였습니다. 

[코드 3-2] (코드3) 코드 조각
var processes =
    from p in Process.GetProcesses()
    orderby p.WorkingSet64 descending
    select p;
int i = 2;
foreach (var p in processes.Take(10))
{
    ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
    ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;

    i++;
}

그리고 현재 컴퓨터의 운영중인 프로세스를 조회한 다음 링큐와 enumable 타입을 사용하여 각 셀에 바인딩하는 모습도 볼수 가 있습니다. 다음으로는 차트 생성 메소드를 활용하여 차트를 생성하고 새로운 워드 문서에 차트 이미지를 복사를 하는 데이터 플로우 입니다.

[코드 3-3] (코드3) 코드 조각
Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);

chart.ChartWizard( range.CurrentRegion, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
"Memory Usage in " + Environment.MachineName, Type.Missing, Type.Missing, Type.Missing);

chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
      Excel.XlCopyPictureFormat.xlBitmap,
      Excel.XlPictureAppearance.xlScreen);

var word = new Word.Application();
word.Visible = true;
var missing = Type.Missing;
word.Documents.Add(ref missing, ref missing, ref missing, ref missing);
word.Selection.Paste();

지금부터 개선된 특징을 적용 시켜야 할텐데요. 우선 그 대상이 무엇인지 살펴보면서 코드를 변경 해보도록 하겠습니다.
여러분들은 코드 3-1, 3-2, 3-3에서 블록 처리 되어 있는 코드를 살펴보시면 됩니다.

우선 [코드3-1]에 workbook에 Add 메소드에 매개변수가 그 변경 대상이 되며 다음으로는 형변환을 포함하여 Value2 프로퍼티가 변경 대상이 되며 다음과 같이 수정을 할 수 있습니다.

[코드 4-1] (코드 3-1)을 Fx4 특징으로 변경 
var excel = new Excel.Application();
excel.Workbooks.Add(Type.Missing);
excel.Workbooks.Add();
excel.Visible = true;

((Excel.Range)excel.Cells[1, 1]).Value2 = "Process Name";
((Excel.Range)excel.Cells[1, 2]).Value2 = "Memory Usage";

excel.Cells[1, 1].Value = "Process Name";
excel.Cells[1, 2].Value = "Memory Usage";


[코드3-2]에서 foreach문 내부의 range 부분도 또한 다음과 같이 수정이 가능합니다.

 [코드 4-2] (코드3-2)을 Fx4 특징으로 변경 
var processes =
    from p in Process.GetProcesses()
    orderby p.WorkingSet64 descending
    select p;
int i = 2;
foreach (var p in processes.Take(10))
{
    ((Excel.Range)excel.Cells[i, 1]).Value2 = p.ProcessName;
    ((Excel.Range)excel.Cells[i, 2]).Value2 = p.WorkingSet64;

    excel.Cells[i, 1].Value = p.ProcessName;
    excel.Cells[i, 2].Value = p.WorkingSet64;

    i++;
}

[코드3-3] 차트에서도 형변환을 포함하여 Add 메소드에 매개변수인  missing, activeSheet, Missing, Missing 인자들도 그 변경 대상이 됩니다. 표현하고자 하는 데이터는 두번째 매개변수이며 파라미터 명칭을 찾아보시면 After이름을 가졌네요.

[그림 1] (코드3-3) Charts.Add 인첼리스트

[코드 4-3] (코드3-3)을 Fx4 특징으로 변경
Excel.Chart chart = (Excel.Chart)excel.ActiveWorkbook.Charts.Add(
Type.Missing, excel.ActiveSheet, Type.Missing, Type.Missing);

Excel.Chart chart = excel.ActiveWorkbook.Charts.Add(After: excel.ActiveSheet);


코드를 다시 내려다 보시면 알수 없는 타입이 선언 되어 있는데요.
(Type.Missing, Type.Missing, Type.Missing, Type.Missing....)  이 코드 또한 변환 대상이 됩니다.

똑같이 적용을 해보면 다음과 같습니다.

[코드 4-4] (코드3-3)을 Fx4 특징으로 변경
chart.ChartWizard( range.CurrentRegion, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
"Memory Usage in " + Environment.MachineName, Type.Missing, Type.Missing, Type.Missing);
chart.ChartWizard(Source: range.CurrentRegion, Title: "Memory Usage in " + Environment.MachineName);

[그림 2] (코드3-3) chart.ChartWizard 인첼리스트



다시 아래 코드를 보시면 새로운 워드 문서를 추가하는 코드를 볼수 있습니다.
missing 타입을 ref 형태로 전달을 하기에 이것 또한 변경을 해줘야겠죠?

[코드 4-5] (코드3-3)을 Fx4 특징으로 변경
var word = new Word.Application();
word.Visible = true;
var missing = Type.Missing;
word.Documents.Add(ref missing, ref missing, ref missing, ref missing);

word.Documents.Add();

word.Selection.Paste();

이렇게 코드를 다시 정리를 해보면 다음과 같습니다.
[코드 5] COM-Specific Interop Sample Fx4
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace HelloFx4_3_OfficeDynamicMappingSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var excel = new Excel.Application();
            excel.Workbooks.Add();
            excel.Visible = true;
            excel.Cells[1, 1].Value = "Process Name";
            excel.Cells[1, 2].Value = "Memory Usage";

            var processes =
                    from p in Process.GetProcesses()
                    orderby p.WorkingSet64 descending
                    select p;

            int i = 2;
            foreach (var p in processes.Take(10))
            {
                excel.Cells[i, 1].Value = p.ProcessName;
                excel.Cells[i, 2].Value = p.WorkingSet64;
                i++;
            }

            Excel.Range range = excel.Cells[1, 1];
            Excel.Chart chart = excel.ActiveWorkbook.Charts.Add(After: excel.ActiveSheet);

            chart.ChartWizard(Source: range.CurrentRegion, Title: "Memory Usage in " + Environment.MachineName);

            chart.CopyPicture(Excel.XlPictureAppearance.xlScreen,
                   Excel.XlCopyPictureFormat.xlBitmap,
                   Excel.XlPictureAppearance.xlScreen);

            var word = new Word.Application();
            word.Visible = true;

            word.Documents.Add();
            word.Selection.Paste();
        }
    }
}

정리를 하였지만 아직 PIA 인터페이스를 응용 프로그램에 포함시키지 않았습니다.

내장하려면 참조되고 있는 어셈블리어 Excel, word, Core등의 어셈블리어를 선택하시고 프로퍼티에 Embed Interop Type 옵션을 True로 변경 해야합니다. 

[그림 3] Embed Interop Type 설정


이렇게 True로 설정하게 되면 컴파일 타임에서 등록해야하는 레지스터리를 사전에 코드에 내장을 하여 불필요한 타입 패턴을 일치 하실 필요가 없으며 런타임 시점에서 dynamic mapping을 하게 됩니다.

[소스 참고]Hello .NET Framework 4 세미나[세션3] 발표자료와 소스 : 
http://blog.tobegin.net/35

참고 문헌
1. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

2. New Features in C# 4.0 - Mads Torgersen, C# Language PM, April 2010
    :
http://msdn.microsoft.com/ko-kr/vcsharp/ff628440(en-us).aspx
3. 방법: Visual C# 2010 기능을 사용하여 Office Interop 개체에 액세스(C# 프로그래밍 가이드)
    :
http://msdn.microsoft.com/ko-kr/library/dd264733.aspx


포스팅을 마치며...

짧게 리뷰를 해보았는데요. 어떠셨는지 모르겟어요 ^^;
제법 강력해졌다라고 표현을 해드리고 싶습니다. 또한 NO-PIA 옵션으로 하위 버전에서 해당 구문이 실행이 가능하다는 사실 잊지마시구요 이제 NO-PIA 옵션을 활용 해보세요 : )

더 궁금하신점이 있으시면 댓글 혹은
http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.

다음 포스팅은 공변성과 반공변성(Co-Variance and Contra-Variance)에 대해서 살펴보도록 하겠습니다.
감사합니다.

정은성 드림


PS. 이번주는 태풍이 온다네요. 우산 꼭 챙기세요 ^ㅁ^
Posted by LenAWeb

댓글을 달아 주세요

  1. 매우 지원, 아주 좋아.

    2013.04.05 16:27 [ ADDR : EDIT/ DEL : REPLY ]
  2. 헤여졌다한들 슬퍼하지마. 이후에 만나게될 더좋은 사람을 위해 항상 웃는얼굴 잃지 말자.

    2013.04.07 00:43 [ ADDR : EDIT/ DEL : REPLY ]
  3. 당신이 슬퍼 느낄 때 고통, 무슨 내용을 보려면하는 것이 가장 좋습니다. 학습은 천하무적 할 것입니다.

    2013.04.08 00:44 [ ADDR : EDIT/ DEL : REPLY ]
  4. 모든 사람은 죽는다. 하지만 모든 사람이 진정한 삶을 사는 건 아니다.

    2013.04.08 08:21 [ ADDR : EDIT/ DEL : REPLY ]
  5. 당신이 슬퍼 느낄 때 고통, 무슨 내용을 보려면하는 것이 가장 좋습니다. 학습은 천하무적 할 것입니다.

    2013.04.09 21:14 [ ADDR : EDIT/ DEL : REPLY ]
  6. http://www,Topics related articles:


    http://webstoryboy.com/256 复件 (10) 韩

    .xn--6ck2bwcu74pofcq24aotk.com/
    http://www,Topics related articles:


    http://important.tistory.com/420 复件 (10) 韩

    .lisseurghdle,Topics related articles:


    http://www.hanbajo.com/?page=3 复件 (15) 韩

    .com/

    2013.04.22 06:44 [ ADDR : EDIT/ DEL : REPLY ]
  7. 지금은 반짝반짝 빛이 나겠지,, 하지만 시간이 흐르면 그빛은 사라저버릴거야,지금 우리처럼

    2013.04.23 21:02 [ ADDR : EDIT/ DEL : REPLY ]
  8. 슬퍼서 우는거 아니야..바람이 불어서 그래..눈이 셔서..

    2013.07.17 11:39 [ ADDR : EDIT/ DEL : REPLY ]

 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance

05| 명명된 인수와 선택적 인수
(
Optional and Named Parameters)

구독자 여러분 안녕하세요
오랜만이시죠? ^^ 이제 저녁 온도가 제법 차가워지고 있네요.. 가을이 오려나봅니다.
건강에 유념하시길 바라구요 바로 포스팅 시작하도록 하겠습니다.

지난 시간에 이어서 오늘 다뤄볼 내용은 바로 명명된 인수와 선택적 인수(Optional and Named Parameters) 입니다. 누구나 개발을 하시다보면 종종 긴 파라미터를 정의를 해야할 때가 있는데요. 그 시그니처를 일치시키기 위해서 그 순서를 맞추려고 노력을 하거나 COM Interop에서 의미 없는 값을 전달을 하기 위해서 불필요한 코딩을 반복해왔습니다.

C# 4.0에서는 이러한 불필요한 코딩을 기본값을 설정을 하여 생략할 수 있게 개선이 되었는데요.
다음 예제 코드를 살펴보시면서 어떻게 개선이 되었는지 살펴보도록 하겠습니다.

[코드 1-1] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }
1)  M(1, 2, 3);
2)  M(1, 2);
3)  M(1);

4)  M(1, z:3);
5)  M(x:1, z:3);
6)  M(z:3, x:1);


코드를 보시면 " 나는 저 코드와 유사하게 사용을해봤어 " 라고 생각을 하실분이 계씰것 같습니다.
구독자분들 중에 아이폰 어플리케이션을 개발을 해보신분이시거나 플렉스를 개발해본 경험이 있으시다면 바로 4~6번 코드와 같이 Named Parameter 방식으로 오브젝트를 활용을 해보신 경험이 있으실것 같습니다.

이기능은 두 언어로부터 유례된 것은 아니지만 앞서 소개해드린 Named Parameter,Optional parameter 방법이 개선이 되면서 어플리케이션 개발에 있어 코드 구성이 간결해지고 읽기 쉬운 코드를 작성이 가능해 졌습니다.

지금 부터 여러분들은 블록(색깔 블록)으로 처리한 부분을 유심히 살펴보실 보셔야합니다.
코드를 보시면 기존의 C# 코드와 다르게 매우 독특한 의미를 가지고 있는데요.

[코드 1-2] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

매소드 문장을 보시면 파라미터 타입을 정의하고 파라미터  이름인 int y와 int z에 5와 7의 숫자를 초기화하는 모습을 볼 수 있습니다. 기존에 볼 수 없었던 문장이지만 정의된 것과 같이 int y와 int z는 optional parameter를 정의하여 초기화 함으로써 옵셔널하게 그 매개변수나 메소드를 사용할 수 잇게 되었습니다. 무슨뜻이냐하면 일반적으로 객체를 생성하여 초기화 하거나 같은 이름을 가진 메소드를 정의를 할 수 있는데요. 보시는 코드와 같이 호출 지점에 대해서 컴파일을 하려고 할때 심덱스 에러가 나타나지 않으려고 한다면 같은 이름을 가진 메소드를 5번 정의를 해야합니다.

이제 부터는 Optional parameter를 활용하여 메소드가 5개 형태가 아니라
하나로 원하는 시그니처 만큼 표현이 가능해졌습니다.

[코드 1-3] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

1)  M(1, 2, 3);
2)  M(1, 2);
3)  M(1);


두번째 코드는 객관적으로 보실 때 가장 일반적인 메소드 형태 이거나 오버로딩이 가능한 메소드 형태들인데요. 원래는 각각의 시그너처 별로 메소드를 정의를 해야하는데요. 이것 또한 Optional Parameter방법을 정의 함으로써 매개변수를 생략을 할 수 있고 생략을 하더라도 매개변수의 값을 전달 할수 있습니다.

 [코드 1-4] Optional and Named Parameters Sample
public void M(int x, int y= 5, int z = 7) { ... }

4)  M(1, z:3);
5)  M(x:1, z:3);
6)  M(z:3, x:1);


마지막 코드를 보시면 파라미터 명칭에 무언가를 주입하려고 하고 있는데요
C# 4.0에서는 Named Parameter 방법이 지원을 함으로써 매개변수의 순서와 관계없이 데이터를 바인딩 할수 있게 되었습니다. 결과를 보시면서 알아보도록 하겠습니다.

[결과 1] Optional and Named Parameters
public void M(int x, int y= 5, int z = 7) { ... }
1)  M(1, 2, 3);              // 1, 2, 3
2)  M(1, 2);                 // 1, 2, 7
3)  M(1);                    // 1, 5, 7

4)  M(1, z:3);              // 1, 5, 3
5)  M(x:1, z:3);           // 1, 5, 3
6)  M(z:3, x:1);           // 1, 5, 3


이미 말씀 드린것과 같이 매개변수가 순서와 관계없이 데이터를 바인딩 할 수 있다고 말씀을 드렸습니다.
4~6번 코드는 매개변수 z와 x에 대해서 명시적으로 할당을 하고 있습니다. 그래서 결과는 위와 같습니다.

아직 이해를 하지 못하셨다면 또 다른 예제를 준비 하였는데요.
이번에는 구독자 분께서 컴파일러가 되어 어떤 호출을 할 때 어떤 메소드가 호출이 될지를 이해하고자 준비해보았습니다.
다음 예제코드를 보시면서 알아보도록 하죠.

[코드 2-1] Optional and Named Parameters
1)  M(String x , int y=1) { … }
2)  M(object x) { … }
3)  M(int x, string y= "hello") { … }
4)  M(int x) { … }


위 예제코드를 보시면 4가지 오버로딩이 가능한 후보들이 있습니다.
그리고 이때 Caller는 다음과 같습니다.

[코드 2-2] Optional and Named Parameters

호출 : M(5);

이제 컴파일러 입장에서 유추를 해봐야할 것 같은데요. 어떤 메소드가 어떻게 호출이 되어질까요?
제가 하나씩 풀이를 해보도록 하겠습니다.

1) 메소드는 y를 생략을 할수 있지만 x 타입과 일치하지 않기 때문에 후보 대상이 될 수 없습니다.
2) 메소드는 object 타입으로 데이터를 받아도 무방하기 때문에 후보가 됩니다.
3) 메소드는 x 타입과 매칭이 되고 y 매개변수는 생략이 가능하기 때문에 이것 또한 후보가 됩니다.
4) 메소드는 x타입과 매칭이 되기 때문에 후보가 됩니다.

다시 정리를 하자면 1) 메소드는 후보 대상이 될 수 없기 때문에 판단 기준에서 제외가 될것이며 2~4번 메소드 중에서 호출이 되어질텐데요. 가장 유력한 후보는 바로 4) 메소드입니다 이유는 타입이 가장 최적화된 시그니처를 가지고 있기 때문인데요.
2) 메소드는 Object로 받을수 있지만 Boxing / UnBoxing을 하기 때문에 성능상으로 좋아 보이지 않으므로 후보대상이지만 3~4번 메소드보다 좋지 않습니다. 3) 메소드는 Optinal parameter에 의해 생략이 가능하기 때문에 후보 대상이지만  아무래도 시그니처 패턴이 퍼펙트한 4번이 호출 될수 밖에 없습니다.

즉, 컴파일러는 호출하려고 하는 시점에서 파라미터가 온 결과를 보고 가장 최적화된 시그니처를 검사를 하게 됩니다. 만약 검사에서 성립이 되지 않으면 옵셔널 파라미터에 의해 메소드를 호출하게 됩니다.

정적 시그너처 체크 -> 옵셔널 파라미터 시그니처 체크 ->  동적타입 사용시 Runtime에서 해당 메소드 체크

Named and Optinal Parameters에서 단순히 코드를 줄여주는 역할 뿐만 아니라 가독성을 높여줍니다.
적절한 사례가 될지 모르겠지만 상황을 들어보도록 하겠습니다.

또와 둘리라는 개발자가 있습니다. 그리고 A라는 메소드를 공용으로 사용 해야한다고 가정을 하겠습니다. 마침 좀더 잘난 또치가 그 메소드를 디자인을 하게 되었는데요. 또치가 설계한 메소드의 매개변수로는 회원번호, 이름, 전화번호, 주민등록번호 순으로 구성을 하였습니다. 근데 둘리가 A라는 메소드를 사용을 할때 너무 코드가 들숙날숙하게 보여서 많이 불편했나봅니다. 둘리라는 개발자가 보는 관점에서는 주민등록번호를 먼저 사용을 해야 했기 때문에 코드가 작성에 가독성이 많이 떨어졌습니다. 그래서 수정을 요청을 했지만 또치가 보기에는 회원 번호가 우선적으로 표기가 되었어야 했습니다. 결국 불편하지만 둘리 개발자는 또치 개발자가 정의해둔 시그니처 패턴에 맞게 작성을 할 수 밖에 없었습니다. 

구독자 여러분들이 이 상황에서 어떻게 하시겠습니까? 당연히 Named Parameter 방법을 아셨으니깐 상황이 오신다면 시그니처를 변경하셔서 개발상에 전혀 문제 없이 즐거운 프로그래밍을 할수 있습니다.

그래도 너무 많이 남용하신다면 가독성이 떨어지기 때문에 필요한 시점에서만 사용하시기를 권장합니다.

와우!! 신기하지 않으신가요? 저 감탄까지 했어요 ^^

좀더 이해를 돕기 위해서 예제코드를 준비 해보았는데요.. 어떻게 사용하는지를 보시죠.

[코드 3] Optional and Named Parameters

namespace HelloFx4_3_NamedNOptionalParameters
{
    class Program
    {
        static void Main(string[] args)
        {
            People("정은성", 27, "남자");
            People("정은성", 27);
            People("정은성");
            People("정은성", Sex:"남자", Age:27);
        }

        private static void People(string Name, int Age = 27, string Sex = "남자")
        {
            Console.WriteLine(string.Format("이름은? {0}, 나이는? {1}, 성별은?{2}", Name, Age, Sex));
        }
    }
}



People메소드를 또 호출하려고 하는데. 코드를 작성하려고 하니깐 인첼리스트 기능에 메타정보가 나타나게 됩니다.

흔히 생략을 할 때 쓰는 중괄호가 보이는데요. 이제부터는 이 매개변수는 생략이 가능하고 생략을 한다면 묵시적으로 데이터가 전달 됩니다. 위 예제 코드는 매개변수를 옵셔널하게 정의를 해주며 생략이 가능한 모습을 보여드리기 위해서 짧게 다루어보았는데요. 다음 포스팅(Com-specific interop features)에서 혼합된 예제를 보여드리도록 하며 이번 포스팅을 마치도록 하겠습니다.

[소스 참고]Hello .NET Framework 4 세미나[세션3] 발표자료와 소스 : http://blog.tobegin.net/35

참고 문헌
1. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

2. New Features in C# 4.0 - Mads Torgersen, C# Language PM, April 2010
    :
http://msdn.microsoft.com/ko-kr/vcsharp/ff628440(en-us).aspx
3. 명명된 인수와 선택적 인수(C# 프로그래밍 가이드)
    : http://msdn.microsoft.com/ko-kr/library/dd264739.aspx


포스팅을 마치며...

명명된 인수와 선택적 인수(Optional and Named Parameters) 포스팅 어떠셨나요?
이 기능 덕분에 코드가 심플해졌고 시그니처에 구해받지 않고 명명 할당이 가능해져서 기쁘네요 : )

다음회차에서는 COM 상호운용성(Com-specific interop features)에 대해서 다뤄볼 예정이며
COM 상호운용성 개선 사항 또한 오피스 프로그래밍을 자주 다뤄보신 분이라면 강력하다 라는 말을 하실겁니다.

더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.

밤낮 기온이 점점 심해지고 있는데요 건강에 유념하시길 바라며 좋은 하루 되세요 : )
감사합니다.

정은성 드림

Posted by LenAWeb

댓글을 달아 주세요

  1. 인연은 우연히 찾아오고 사랑은 조심스럽게, 몰래 찾아온다.

    2013.04.07 23:44 [ ADDR : EDIT/ DEL : REPLY ]
  2. 그들은 화려한되지 않기 때문에 어떤 사람들은 대단하지 않을 지출하지만, 자신의 마음이 멋진 아이디어를 스쳐하지 않았기 때문에, 또는 얼마나 영리 모르겠어요.

    2013.04.08 22:07 [ ADDR : EDIT/ DEL : REPLY ]
  3. http://www.xn--6ck2bwcu74pofcq24aotk,Topics related articles:


    http://visionandlogic.net/340 复件 (13) 韩

    .com/
    http://www,Topics related articles:


    http://game1112.tistory.com/128 复件 (16) 韩

    .lisseurghdle,Topics related articles:


    http://december08.tistory.com/m/post/view/id/612 复件 (11) 韩

    .com/

    2013.04.21 09:48 [ ADDR : EDIT/ DEL : REPLY ]
  4. http://www.saclongchampxl,Topics related articles:


    http://www.blue2sky.com/780 复件 (17) 韩

    .com/
    http://www,Topics related articles:


    http://myipcam.kr/973 复件 (11) 韩

    .nikeairmaxfrse,Topics related articles:


    http://naturalstyle.kr/?page=21 复件 (19) 韩

    .com/

    2013.04.21 18:25 [ ADDR : EDIT/ DEL : REPLY ]
  5. 귀를 기울여봐 가슴이 뛰는 소리가 들리면 네가 사랑하는 그 사람 널 사랑하고 있는거야.

    2013.04.23 14:46 [ ADDR : EDIT/ DEL : REPLY ]
  6. 지금은 반짝반짝 빛이 나겠지,, 하지만 시간이 흐르면 그빛은 사라저버릴거야,지금 우리처럼

    2013.07.17 03:25 [ ADDR : EDIT/ DEL : REPLY ]

 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance

04| Dynamic 유형 객체 #2 : Dynamic lookup
말 못할 일상생활에 빠져 포스팅이 늦어버렸네요. 흑흑..어쨌든 프로젝트 투입전까지 포스팅을 마무리 짓겠습니다.

오늘 다뤄볼 내용은 바로 Dynamic lookup인데요. Dynamic lookup과 함께 C# 4.0에서 가장 큰 변화라고 하면 바로 Dynamic 키워드 도입이라고 할수 있습니다. 이번 포스팅에서는 Dynamic이 어떤 의미를 가지고 있고 Dynamic lookup을 통해 duck Typing의 프로그래밍 스타일에 대해 알아보도록 하는 시간을 가져보도록 하겠습니다.


Dynamic에 대해서 생각을 해보시면 무언가 굉장히 추상적이다 라는 의미를 알 수 있습니다.
C# 4.0의 PM인 Mads Torgersen이 기술한 New Features in C# 내용을 인용한다면 다음과 정의 할 수 있습니다.

- The Dynamic Type
- Dynamic Operations
- Runtime Lookup
   가. COM objects(COM IDispatch)
   나. Dynamic Objects
        (IDynamicObject, IronPython, IronRuby, HTML DOM)
- Plain object(.NET object reflection etc)

위 표를 보시면 동적 유형, 동적 연산, 런타입 룩업, 일반 개체로 나누어져 있습니다.
이번 포스팅에서는 전부 살펴볼수 없기에 그 중동적 유형, 동적 연산, 런타임 룩업에 대해서 살펴보도록 하겠습니다.

* 동적 유형(Dynamic Type)

C# 4.0에서 새로운 정적 타입의 동적 키워드를 소개를 하고 있습니다. 동적 유형의 오브젝트를 사용할 때는 런타임 에서만 그 타입을 결정 할 수 있는데요. 먼저 코드를 살펴보도록 하겠습니다.

[코드 1] Dynamic Type Sample
dynamic d = GetDynamicObject(...);
d.M(7);

겉모습으로 볼때 반환하는 메소드 형태와 큰 차이는 없어 보입니다. 그러나 이미 여기서 코드를 보시면서 의문을 가지신분들이 계실것 같은데요. 바로 dynamic 키워드와 GetDynamicObject 메소드의 관계가 굉장히 의심 스럽습니다.
GetDynamicObject 이름을 가진 메소드는 어떤 타입을 가지고 반환하는지 알수가 없을 뿐만 아니라 dynamic이라는 키워드의 변수에 할당하는 모습이 예사롭지 않다는 사실을 알수 있습니다.

C# 4.0 컴파일에서는 GetDynamicObject 메소드와 같이 어떤 이름과 어떤 인수를 가진 메소드든 간에 동적 타입에게 할당할 경우 허용을 하고 있습니다. 이유는 dynamic 형식은 정적 형식이지만 정적형식 검사에서 제외됩니다.

이형식의 타입을 사용하는 개체에서 값을 가져오는 소스가 COM API, Ironpython과 같은 동적언어, DOM 개체모델 등 프로그램 내부인지 다른 위치인지 또는 리플렉션이라도 신경 쓰지 않으셔도 됩니다.
여기서 동적 타입 개체는 바로 d인데요.
개체 d는 어떤 메소드를 호출 하려고 액션을 취하고 있습니다.
앞서 말씀을 드렸듯이 동적 유형의 오브젝트를 사용할때에는 런타임에서만 그 타입을 결정을 할수 있기 때문에 컴파일 시점에는 알수는 없습니다. 결국 런타임시점에서 d는 M에 관련된 가장 적합한 메소드를 찾게 되며 매개변수로 전달되는 심볼 유형이 숫자이기때문에 int형 매개변수를 가진 메소드를 호출하게 됩니다.


그래도 이해가 되지 않으셨다면 간단한 예제 코드를 살펴보시면 이해가 될것 같네요.

[코드 2] Dynamic Type Sample
dynamic d = 7;
int i = d;

위 코드는 [코드 1]의 d.M(7); 코드 구문을 이해 하고자 간단한 코드를 보였는데요.
dynamic d = 7 수식 같은경우 RValue인 숫자 심볼 7을 LValue인 Dynamic d 변수에 할당하는 모습입니다.
이는 컴파일 타임에서 암시적으로 int형 타입으로 캐스팅하는 행위로 재해석할수 있습니다.

int i = d 수식은 위 수식과 달리 런타임에서 동적타입인 d 변수에 대해서 암시적으로 int형으로 캐스팅이 되어집니다.

* 동적 조작(Dynamic Operations)
Method 호출 뿐만 아니라, Field 접근, Indexer 및 Operator 호출, Constructor 호출, 대리자 형식까지 동적으로 재정의할 수 있습니다.다음 코드를 보시면 동적 조작에 대한 예제에 대해 알수 있습니다.

[코드 3] Dynamic Operations Sample
dynamic d = GetDynamicObject(...);
d.M(7);                         // Method 호출의 예
d.f = d.P;                       // 해당 Field/Property에 대해 Getter/Setter의 예
d["one"] = d["two"];       // Indexer의 예
int i = d + 3;                   // Operator 호출의 예
string s = d(5,7);            // Delegate를 통해 호출의 예
var c = new C(d);          // Constructor 호출의 예

C# 컴파일러의 역할은 단순히 "무엇을 동적"으로 수행되는지에 대해 필요한 정보를 패키지할 뿐만 아니라 런타임에서 그정보가 무엇의 정확한 의미를 가지는지 실제 개체를 동적으로 부여됩니다.

* Dynamic 뭐가 좋아?
그럼 dynamic 키워드가 뭐가 좋은데? 라고 질문을 주실 수 있는데요. 하위 버전의 C# 코드와 비교 해보겠습니다.
[코드 4] Dynamic Sample
[코드 4-1] 정적 타입 유추
Calculator calc = new Calculator();
int sum = calc.Add(10, 20);

[코드 4-2] 컴파일 타입 유추
var calc2 = new Calculator();
int sum2 = calc2.Add(10, 20);

[코드 4-3] 런타임 타입 유추
dynamic calc = GetCalculator();
int sum = calc.Add(10, 20);

첫번째 코드[코드 4-1]는 가장 일반적인 정적 타입 유추 코드이며 두번째[코드 4-2] var 키워드의 특징을 이용하여 존재하지 않지만 컴파일 타임에서 Calculator라는 클래스임을 판단하여 타입을 유추를 하게 되고 해당 두 숫자를 합하여 sum varable에 값을 반환을 하게 됩니다. 세번째 코드[코드 4-3]에서는 dynamic 타입을 사용하였는데요 dynamic 타입은 실행시간을 지연하여 런타임에서 타입을 유추를 하게 됩니다. 처음 Dynamic 에 대해서 설명을 드렸듯이 정적타입 검사에서 Add라는 메서드는 제외가 되므로 런타임에서 바인딩 되어 동적으로 호출합니다.

여기서 만약에 dynamic 키워드가 없다면 어땠을까요?

dynamic  키워드가 없었다면 다음과 같이 작성을 해야합니다.
[코드 5] Reflection Sample
object calc = GetCalculator();
Type calcType = calc.GetType();
object res =  calcType.InvokeMember("Add", BindingFlags.InvokeMethod,                      
                                                        null, new object[] { 10, 20 }); int sum = Convert.ToInt32(res);

GetCalculator 클래스가 다른 외부의 객체 모델(Object Model) 은 아니지만 외부 객체라고 가정을 해보겠습니다.
근데 성능상 좋지는 않아보입니다. 왜냐하면 Variant를 위해 불필요하게 object 형식을 다시 해당하는 타입으로 cast을 하고 있는데요. 이는 오버헤드를 발생하게됩니다. 더구나 코드도 어렵네요.

여러분이 객관적으로 보실 때 선택을 한다면 reflection을 사용하시겠습니까?
아니면 dynamic 키워드를 사용하시겠습니까?

이번 포스팅에서 두 특징에 대해서 상세히 다를 순 없지만 간단히 설명을 드리자면 속도면에서 사실상 리플렉션이 더 빠른 결과를 나타내고 있습니다. 그리고 dynamic은 리플렉션에 비해 느리지만 리플렉션의 단점이였던 많은 메모리 소모와 호환성 문제를 높은 수준으로 보장하고 있습니다

여러분들의 코드에 동적으로 무언가를 꼭 해야 한다면 필요한 시점에서 사용하시기를 권장합니다.

* Duck Typing(dynamic lookup)
Dynamic 키워드를 도입을 하면서 dynamic lookup이라는 말과 함께 새로운 동적 프로그래밍 스타일이 이슈가 되었는데요
바로 Duck Typing 이라는 프로그래밍 스타일이 C#에서 가능하게 되었습니다.

위키디피아에서 다음과 같이 정의가 되어 있습니다.
If it walks like a duck and quacks like a duck, I would call it a duck



위 문장을 인용을 한다면 오리처럼 행동하면 오리라 부를 수 있다는 의미로써,
문자열처럼 다루게 된다면 그것이 객체이든 뭐든 상관하지 않고 그객체를 문자열처럼
취급해도 된다라는 이야기입니다.

흔히 알고 있는 상속이나 구현과 같이 해당 객체의 부모나, 인터페이스의 영향아닌 그 오브젝트가 가진 특징에 의해 역활을 결정 되는거죠.

즉, Duck Typing과 같이 룩업을 하게 된다면 어떤 클래스나 인터페이스 타입의 오브젝트인지에 상관없이 호출시 해당 오브젝트 존재하기만하면 사용 할 수 있습니다.





* Dynamic Lookup과 함께 Duck Typing 스타일이 이슈가 된 이유?

어떤 어플리케이션을 만들고 테스트를 해야할 때 일반적으로 mock오브젝트를 만들고 테스트를 하죠? 자바와 같은 Static Typing 언어에서는 mock object를 만들기 위해서 실제 사용할 오브젝트와 동일한 인터페이스를 구현을 해야 합니다. 다형성을 활용하여 구현을 할 수 있지만 만약 인터페이스 내에 메소드가 많다면 테스트와 관계없는 메소드까지 구현을 해야 한다는 단점이 있습니다. 다행히 IDE의 도움으로 쉽게 생성을 할 수 있지만 한 메소드를 테스트하기 위해서 모든 메소드를 구현을 해야한다면 좋지 않겠죠? 정말 비효율적인데요. 이런 바탕으로 프로그래밍 스타일이 이슈가 되게 되었습니다.

다음 데모를 보시면서 " Dynamic Lookup이 이렇게 사용하는구나! " 라고 이해가 될것 같네요.

[코드 6] Dynamic Lookup Sample
var people = new { Name = "정은성", Age = 27 };
PeopleInfo(people);

public static void PeopleInfo(dynamic d)
{
      Console.WriteLine( "이름: {0}, 나이: {1}" , d.Name, d.Age);
}

코드 6번과 동일한 퍼포먼스를 수행하기 위해서는 리플렉션을 이용하거나 해당 매개변수와 동일한 인터페이스를 가지거나 멤버변수를 지정을 해줘야만 PeopleInfo 메소드를 수행을 할수 있었습니다. Dynamic 도입으로 인해 늦은 바인딩이 가능한 모습을 볼수 있습니다. 다음 데모를 통해 Duck Typing에 대해서 더 많은 이해를 할 수 있습니다.

[코드 7] ExpandoObject Sample
      class Program {
        static void Main(string[] args) {
            dynamic people = new ExpandoObject();
            people.Name = "정은성";
            people.Age = new Sameple();      //new Sameple();  or  27
            people.Run = new Action(() => Console.WriteLine("Run 메소드 런타임에서 실행 "));
            printInfo(people);
            people.Run();
        }
        static void printInfo(dynamic info) {
            Console.WriteLine(string.Format("이름{0}, 나이는 {1} 입니다.", info.Name, info.Age));        }
    }
    class Sameple    {
        private int Age = 27;
        public override string ToString() {
            return this.Age.ToString(); }
    }

다음 코드 좀 주목해야할 부분입니다.
people.Age = new Sameple();      //new Sameple();  or  27
일반적인 코드라면 동일한 타입이 아닌 이상 오류가 날수 밖에 없는데요.
C# 4.0에서는 Dynamic Lookup 가능하기 때문에 런타임에서 수행가능한 코드라면 그것이
숫자든 문자열든 관계없이 수행을 할수 있습니다.

people.Run = new Action(() => Console.WriteLine("Run 메소드 런타임에서 실행 "));
람다 문장을 활용하여 해당 메소드를 룩업한 모습을 볼수 있습니다.

[코드 8] IronPython Sample ( ※ DevDays2010에서 선보였던 예제코드를 재구성 )
ScriptRuntime py = Python.CreateRuntime();
dynamic python = py.UseFile("Calculator.py");
dynamic calc = python.GetCalculator();

for (int i = 0; i < 10; i++)
{
    var sum = calc.Add(DateTime.Today, TimeSpan.FromDays(i)); 
    Console.WriteLine(sum);    
}

[소스 참고]Hello .NET Framework 4 세미나[세션3] 발표자료와 소스 : http://blog.tobegin.net/35


참고 문헌
1. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

2. dynamic(C# 참조)
    :
http://msdn.microsoft.com/ko-kr/library/dd264741.aspx
3. The Dynamic Keyword in C# 4.0 - CodeProject
    : http://www.codeproject.com/KB/cs/TheDynamicKeyword.aspx
4. BOO -Duck Typing
    : http://boo.codehaus.org/Duck%2BTyping


포스팅을 마치며...
맨날 바쁘다며 포스팅을 게으르게 올리고 있는데요. 열심히 하겠습니다. 흑흑..

Dynamic Lookup에 관한 포스팅은 여기까지 하도록 하겠습니다.
더 궁금하신점이 있으시면 댓글 혹은 http://blog.tobegin.net/notice/1 프로필정보를 통해 문의 바랍니다.

다음 회차에서는 Optional and Named Parmeters에 대해서 살펴보도록 하겠습니다.
무더위 준비 잘하시고 좋은 하루 되세요 : )
감사합니다.

정은성 드림

Posted by LenAWeb

댓글을 달아 주세요

  1. 매우 지원, 아주 좋아, http://ntu.bottesuggdt.com chaussures ugg.

    2013.04.13 18:39 [ ADDR : EDIT/ DEL : REPLY ]
  2. 희미한 달빛이 샘물 위에 떠있으면,나는 너를 생각한다.

    2013.07.15 07:16 [ ADDR : EDIT/ DEL : REPLY ]

 회차
[C# 4.0] New Features in C# : 01. C# Programing Trend
[C# 4.0] New Features in C# : 02. C# 4.0 Overview
[C# 4.0] New Features in C# : 03. Dynamically Typed Objects #1 : DLR
[C# 4.0] New Features in C# : 04. Dynamically Typed Objects #2 : Dynamic Lookup
[C# 4.0] New Features in C# : 05. Optional and Named Parameters
[C# 4.0] New Features in C# : 06. Com-specific interop features
[C# 4.0] New Features in C# : 07. Covariance and Contravariance

03| Dynamic 유형 객체 #1 : DLR


구독자 여러분 안녕하세요 생각보다 포스팅이 많이 늦어졌죠?
최근에 처리할일이 생각보다 많아서 포스팅을 쓸 여력이 되지 않았습니다.
앞으로 열심히 쓰고자 하니깐 용서해주세요 ~ 흑흑...

오늘은 지난 시간에 이어서 C#의 새로운 기능에 대해 소개를 할텐데요.
그 첫번째 시간으로 동적 타입에 대해 소개를 하고자 합니다.

지난 Microsoft는 MIX07과 PDC2008 등을 통해 .NET에서 새로운 수준의 지원을 발표를 하였습니다.
바로 .NET 프레임워크에서 서로 다른 프로그래밍 언어를 광범위한 지원을 하도록 설계가 되어졌는데요.

그배경에 공용언어 런타임(Common Language Runtime)의 Sandbox 보안 모델이 발전되면서 GC(Garbage Collection), JIT(just-in-time)를 더불어 공유 서비스를 제공하면서 각 다른 언어의 라이브러리를 손쉽게 가져다 쓸수 있었기에 정적인 언어와 동적인 언어를 구별하여 사용할수 있었지 않았나 생각이 듭니다.

* Sandbox(샌드 박스)
보호된 영역내에서 프로그램을 동작시키는 것으로 외부 요인에 의해 악영향이 미치는 것을 방지하는 보안 모델, ' 아이를 모래밭(샌드 박스)의 밖에서 놀지 않는다 ' 라고 하는 말이 어원이라고 알려져 있다. 이모델에서는 외부로부터 받은 프로그램을 보호된 영역, 즉, '상자'안에 가두고 나서 동작시킨다. '상자'는 다른 파일이나 프로세스로부터 격리되어 내부에서 외부를 조작하는 것은 금지 되어 있다.

어느듯 .NET Framework 4 버전의 런칭이 되면서 공용 언어 런타임(Common Language Runtime)이 2.0에서 4.0으로 업그레이드가 되었는데요. 그동안 Silverlight 1.1에서 지원을 했던 DLR(Dynamic Language Runtime)이 다시 주목을 받으면서 C# 4.0은 완전한 프로그래밍으로 초점을 맞추어 나가고 있습니다.

먼저 간단히 DLR(Dynamic Language Runtime)에 대해서 살펴 보아야 할것 같습니다.
Dynamic Language Runtime은 CLR 상단부에 위치하고 있으며 주요 구성은 다음과 같습니다.
[그림 1 : Dynamic Language Runtime Architecture ]

DLR은 3가지 주요 구성요소를 가지고 있는데요. 어떻게 동적 언어를 실행하기 위해 협력을 하는지 설명을 해드리겠습니다. 

- Expression Trees
: 트리를 사용하여 구조적 표현의 의미를 노드로 나타냅니다. 다른 언어의 모델링을 지원하기 위해 확장된 LINQ 표현식 트리를 포함하여 동적인 변수 연산이나 변수, 이름 바인딩과 제어흐름 등이 추가 되어 DLR의 중추 역활을 담당합니다.

  표현 트리식에 대해서 궁금하시면 아래 URL을 참고 해주세요 
  표현 트리식 : 
http://msdn.microsoft.com/ko-kr/library/bb397951.aspx

- Dynamic Dispatch 
: DLR에서는 동적 개체 및 작업을 나타내는 인련의 클래스와 인터페이스를 제공합니다. 언어를 구현하거나 동적 라이브러리를 작성할 때 제공되는 클래스와 인터페이스를 사용할 수 있습니다. 해당하는 클래스와 인터페이스로는 IDynamicMetaObjectProvider, DynamicMetaObject, DynamicObject 및 ExpandoObject가 있습니다.

- Call Site Caching
:  런타임 환경에서 실행되어질 동적 개체 대해서 코드에 대한 정보를 은닉해둠으로써 이후 동일 액션의 호출시 수행속도를 향상하는 역활을 합니다. 예를 들어 a + b와 같은 연산이 있을때 a, b의 특징과 작업 관련된 정보를 캐싱해두었다가. 만약 어떠한 작업을 수행해야할때 이전에 그와 같은 작업을 수행한적이 있다면 DLR에서 캐싱된 내용을 디스패치 하여 속도를 향상시킵니다.

위와 같은 구성원이 서로 협력을 통해  동적 프로그래밍이 각 바인더별로 실행이 가능하도록 지원을 하고 있습니다.
DLR에 대해서는 여기까지 살펴보도록 하고 Dynamic lookup에 대해서 살펴보도록 하겠습니다.
혹 자세한 설명이 필요 하시다면 First Look C# 4.0 whiepaper 를 참고하시거나 별도 포스팅을 기획할 예정입니다

참고 문헌

1. 식 트리(C# 및 Visual Basic)

    : http://msdn.microsoft.com/ko-kr/library/bb397951.aspx

2. PDC2008 : The Future of C# - Anders Hejlsberg
    : http://channel9.msdn.com/pdc2008/TL16/

3. A Dynamic Language Runtime (DLR) - Jim Hugunin's Thinking Dynamic
    :
http://blogs.msdn.com/b/hugunin/archive/2007/04/30/a-dynamic-language-runtime-dlr.aspx
4. DLR Trees (Part 1) - Jim Hugunin's Thinking Dynamic
    : http://blogs.msdn.com/b/hugunin/archive/2007/05/15/dlr-trees-part-1.aspx



포스팅을 마치며...

갑자기 일이 많아져서 포스팅이 늦어졌는데요. dynamic lookup을 살펴보기전에 DLR 존재의 여부에 대해 전달 할 필요가 있는것같아 간소화하게 작성하게 되었는데 왠지 모를 어색하고 주절주절 한 포스팅 이 되어버렸네요 T.T

다음 회차에서는 dynamic lookup의 특징과 C#의 새로운 프로그래밍 스타일인 duck typing 에 대해 살펴볼 예정입니다.
무더위 준비 잘하시고 좋은 하루 되세요 : )
감사합니다.

정은성 드림
Posted by LenAWeb

댓글을 달아 주세요

  1. 그거아니,Topics related articles:


    http://easymusic.co.kr/94 韩

    ,세상에너밖에없어서,Topics related articles:


    http://unendinglove.co.kr/1493 复件 (2) 韩

    ,널사랑하는게아니라,널사랑하니까,Topics related articles:


    http://www.chunhwa244.net/category/들마는달린다 复件 (15) 韩

    ,세상에너밖에없다는거

    2013.04.11 01:36 [ ADDR : EDIT/ DEL : REPLY ]
  2. http://www,Topics related articles:


    http://no-surrender.tistory.com/369 复件 (20) 韩

    .christianlouboutinve,Topics related articles:


    http://hancd.com/archive/201209 复件 (17) 韩

    .com http://www.cheapshoesec,Topics related articles:


    http://www.cafeleeu.com/archive/20120409 复件 (14) 韩

    .com/

    2013.04.22 01:01 [ ADDR : EDIT/ DEL : REPLY ]
  3. 슬픔을 나누면 반으로 되지만, 기쁨을 나누면 배가된다.

    2013.04.23 20:56 [ ADDR : EDIT/ DEL : REPLY ]
  4. 다른 남자 부르면서 울거면 나한테 이쁘지나 말던지

    2013.04.28 06:37 [ ADDR : EDIT/ DEL : REPLY ]
  5. 창밖을 봐 바람에 나뭇가지가 살며시 흔들리면 네가 사랑하는 사람이 널 사랑하고 있는거야.

    2013.07.18 06:53 [ ADDR : EDIT/ DEL : REPLY ]