• 다중 파일 어셈블리

    • myAseembly.dll에 포함된 세 개 파일 모두 하나의 어셈블리에 속함

    • 하지만 파일 시스템에서는 이들 파일을 세 개의 개별 파일로 인식

    • Util.netmodule 파일은 아무러 어셈블리 정보를 포함하지 않기 때문에 모듈로 커파일

    • 어셈블리가 만들어질 때 MyAssembly.dll과 Util.dll및 Graphic.bmp와의 관계를 나타내도록 어셈블리 매니페스트가 MyAssembly.dll에 추가된다.

    • 코드 디자인시 단일 파일 어셈블리로 구성할 지, 다중 파일 어셈블리로 구성할 지, 다중 파일 어셈블리로 구성한다면 어떻게 구조화할 것인지를 결정해야함.

 

  • namespace와 assembly

    • namespace : data type들을 그룹화하는 논리적 개념

      • 하나의 네임스페이스는 여러 개의 어셈블리로 구성되어 질 수 있고,

      • 하나의 어셈블리는 여러 개의 네임스페이스로 구성되어질 수 있다.

  • 다중 파일 어셈블리 만들기

    • 다른 언어로 작성된 모듈을 결합하려는 이유로 사용

    • 자주 사용되지 않는 data type에 대해 필요할 때만 다운로드 되도록 모듈로 분리하고자 할 때 사용

    • Enterprise 환경에서 개발시 여러 개발자가 각각의 모듈로 생성하고, 이를 하나의 어셈블리로 통합

    • 생성 방법

      • 1단계 : 어셈블리를 구성하는 부속 파일에 대한 모듈 생성

      • 2단계 : 다른 모듈에 대한 참조를 사용하여 주 모듈 컴파일

        • /addmodule : 옵션을 사용하여 1단계에서 생성한 부속모듈에 대한 reference 추가

      • 3단계 : 어셈블리 링커를 사용하여 다중 파일 어셈블리 만들기

    • 1단계 : 어셈블리를 구성하는 부속파일에 대한 모듈 생성

 csc /t:module MyCode.cs // MyCode.netmodule 이라는 모듈 생성

 csd /out:util.netmodule /t:module MyCode.cs  // 모듈명 지정하여 생성

    • 2단계 : 부속 모듈에 대한 참조를 사용하여 주 모듈 컴파일

 csc /addmodule:util.netmodule /t:module Client.cs

 // Client.netmodule을 생성하면서 util.netmodule에 대한 reference 추가

      • 위 두 과정을 하나의 명령문으로 처리 가능

 csc /out:Client.exe Client.cs /out:util.netmodule MyCode.cs

 

    • 3단계 : 어셈블리 링커를 사용하여 다중 파일 어셈블리 만들기

      • al<moudle name> <module name>...

      • /out:<file name>

      • /main:<method name>

      • /target:<assembly file type>

 al Client.netmodule util.netmodule /main:MainClientApp.Main /out:MyAssembly.exe /target:exe

 

 

  • 어셈블리 링커

    • Assembly Linker는 모듈 또는 리소스 파일인 하나 이상의 파일에서 어셈블리 매니페스트가 있는 파일을 생성

      • /out : 필수옵션으로 AL이 만드는 파일의 이름을 지정

      • /embed : 모듈이 지정하는 리소스를 어셈블리 매니페스트가 포함된 이미지에 포함시킨다.

      • /link : 리소스 파일을 어셈블리에 링크

      • /main : 모듈을 실행 파일로 변환할 때, 실행 파일의 진입점에 해당하는 method

      • /target : 출력 파일의 파일 형식을 lib(코드 라이브러리), exe(콘솔 응용 프로그램) 또는 win(Windows 기반 응용 프로그램)으로 지정, default는 lib

 

[첨부 파일 : 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 동영상 강좌

  • COM에 대하여

    • 이미 사용중인 검증된 코드의 재사용을 위해 COM 활용

    • 서로 다른 언어로 작성된 바이너리의 타입을 공유하기 위한 방법으로 COM 서버 생성

    • 버전관리의 문제

      • Client에서 COM 서버를 호출할 때 COM 서버의 버전을 확인할 방법이 제공되지 않는다.

      • 때문에 새로운 버전의 COM 서버를 설치하면 타입라이브러리를 새로 수정하고, 레지스트리를 업데이트하며, 상황에 따라 Client의 코드를 수정하는 상황도 발생(DLL 지옥)

    • 배포의 문제

      • COM 서버의 정보를 레지스트리에 등록하는 과정은 어렵지 않다.

      • 하지만 COM 서버의 위치나 이름이 바뀌게 되면, 레지스트리 변경이 쉽지 않게 된다. 이 경우 이 COM 서버를 접근하는 Client의 구성정보를 모두 변경해야 한다.

 

  • 어셈블리(Assembly) 특징

    • DLL 지옥의 탈출

      • 같은 COM DLL에 대한 서로 다른 버전을 동시 제공 가능

      • Client가 원하는 버전을 파악하여 해당 버전의 COM DLL을 정확히 로드

    • 레지스트리에 등록하지 않음

      • 어셈블리는 레지스트리 등록 대신 Assembly 내에 자신에 대한 메타데이터를 포함하게 된다.

      • 배포는 해당 파일을 원하는 위치에 복사하는 것으로 끝남.

    • COM 처럼 dll과 exe의 형태

    • 배포의 단위로써 코드 재사용 및 버전 관리를 가능하게 하는 단위

    • class 접근제한자인 internal의 허용 단위

 

  • Assembly Architecture

    • 하나의 assembly는 다중 모듈로 구성

      • 모듈(module)이란 유효한 파일의 이름으로 소스코드 파일이나 리소스(예 : 이미지 파일)

    • 일반적인 어셈블리는 네 가지 요소로 구성

    • 단일 파일 어셈블리

      • assembly metadata

      • type metadata

      • MSIL 파일

      • 리소스

    • 다중 파일 어셈블리

      • 자주 사용되지 않는 유틸리티 코드를 다른 모듈(별도의 소스파일)로 분리

      • size가 큰 리소스를 분리

      • .NET Framework에서는 파일이 참조될 때만 다운로드 하므로 이처럼 자주 참조되지 않는 코드와 리소스를 다중파일 어셈블리로 분리하여 구성하면 코드를 최적화 시키는 것이 가능

 

  • 어셈블리 매니페스트(Assembly Manifast)

    • Assembly의 핵심요소

      • 어셈블리 참조에 필요한 모든 정보를 내장

      • ID : 이름, 버전, 컬처, 공개 키

      • 파일목록 : 하나의 어셈블리는 하나 이상의 파일로 구성

      • 참조된 어셈블리 목록 : 외부에서 참조되는 어셈블리에 대한 정보

      • Permission 정보 : 이 어셈블리를 실행하기 위해 필요한 권한 정보

      • 형식 참조 정보 : reference와 그 reference의 선언/구현 사항이 포함된 파일을 매핑하는 정보

 

  • 매니페스트의 저장 방법

    • 단일 파일 어셈블리에서는 어셈블리를 구성하는 파일에 포함

    • 다중 파일 어셈블리에서는 별도의 독립실행형 매니페스트를 구성하거나 어셈블리를 구성하는 하나의 dll에 저장될 수 있다.

 

  • 단일 파일 어셈블리 만들기

    • 어셈블리 매니페스트, 형식 정보, 구현 코드 등의 하나의 파일로 구성된다.

    • 생성

csc MyCode.cs // MyCode.cs 모듈에 대한 어셈블리(MyCode.exe) 생성

 

    • 출력 파일명 지정

csc /out:MyAssembly.exe MyCode.cs

 

    • 라이브러리 생성

                    csc /out:MyCodeLibrary.dll /t:library MyCode.cs

 

 

  • 공유 어셈블리와 전용 어셈블리

    • 공유 어셈블리(shared assembly)

      • 재사용 가능한 코드에 대한 어셈블리의 생성(COM의 dll, exe처럼)

      • SN(Strong Name)을 가지고 있어야 한다.(sn.exe)

        • 버전 정보를 포함하고 있어야 한다.

      • GAC(Global Assembly Cache)에 등록해야 한다.(gacutil.exe)

    • 전용 어셈블리(private aseembly)

      • 응용 프로그램과 동일한 디렉토리 또는 서브 디렉토리에 존재

      • 버전관리나 클래스 이름 충돌의 문제가 없음

      • 특정 응용 프로그램에 종속적인 어셈블리를 구성할 때 사용

 

  • 어셈블리 정보 확인

    • Intermediate Language Disassembler Utility

    • ILDasm.exe

      • GUI를 통해 .NET assembly(EXE 혹은 DL)의 정보를 확인할 수 있다.

 

  • 버전 관리

    • 소스 코드 내에서 직접 입력 가능

    • [assembly:AssemblyVersion("1.0.1.0")]

      • 주버전.부버전.수정버전.빌드번호

      • 수정버전과 빌드번호는 *로 생략가능

    • [assembly:AssemblyVersion("1.0.*")]

    • 공유 어셈블리의 경우 버전이 다를 경우 함께 사용할 수 있다(서로 버전의 library를 함께 서비스 할 수 있다.)

 

[첨부 파일 : 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌

  • 전처리기 지시문(Preprocess Directive)

    • Compile 시에만 처리되는 명령문

    • 특정 조건에서만 Compile 되도록 처리하기 위한

    • 여러 버전의 Apllication 생성을 위해

      • standard Edition

      • Enterprise Edition

    • 디버깅 정보를 제공하기 위해

      • Debug를 위한 버전(debugging을 위한 기능 추가)

      • Release를 위한 버전(Debugging을 위한 기능 제거)

    • #으로 시작되는 지시문을 제공

 

  • #define, #undef

    • Compiler에게 해당 기호의 정의 및 제거를 알림

 #define DEBUG            // DEBUG 기호의 정의

 #define ENTERPRISE   // ENTERPRISE 기호의 정의

 #define STANDARD     // STANDARD 기호의 정의

 #undif DEBUG             // DEBUG 기호의 제거

 #undif ENTERPRISE    // ENTERPRISE 기호의 제거

 #undif STANDARD       // STANDARD 기호의 제거

 

    • #if, #endif, #else, #elif 등과 함께 사용

    • attribute와 함께 사용 가능하다

 

  • #if, #endif, #else, #elif

    • 특정코드만 Compile되도록 조건을 명시

 #define ENTERPRISE

 

 #if (ENTERPRISE && STANDARD)

          Console.WriteLine("ENTERPRISE 버전입니다.");

 #elif (STANDARD)

          Console.WriteLine("STANDARD  버전입니다.");

 #else

          Console.WriteLine("TRIAL 버전입니다.");

 #endif

 

  • #warning, #error, #line

    • Compile 시 사용자 정의 메시지를 출력하기 위한 용도

 # if (ENTERPRISE && STANDARD)

          #error ENTERPRISE와 STANDARD가 같이 정의되었습니다.

          Console.WriteLine("ENTERPRISE 버전입니다.");

 #elif (STANDARD)

          #warning STANDARD 버전을 생성하고 있습니다.

          Console.WriteLine("STANDARD  버전입니다.");

 #else

          Console.WriteLine("TRIAL 버전입니다.");

 #endif

 

 #line 24 "여기는 24번 라인입니다." // 24번 라인이 compile 된다는 표시

 

  • #region, #endregion

    • 하나의 코드블럭을 형성하는 단위를 나타냄

    • Visual Studio.NET에서 코드블럭의 확장/축소가 가능함

 

 

[첨부 : 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌

 

  • 객체의 생성과 소멸

    • 객체의 생성

      • new 연산자를 사용하여 class의 instance인 객체(object)를 생성

      • 이 때 객체가 생성되는 곳이 Managed Heap

    • 객체의 소멸

      • C++ 같은 경우 소멸자(destructor)를 정의하여 메모리 관리(리소스 해제)가 가능

      • C# 에서는 Garbage Collector가 메모리를 관리

        • 소멸자가 존재하지만 언제 호출되는지 예측할 수 없다.

        • 때문에 소멸자는 사용하지 않을 것을 권장

      • 불가피하게 객체의 소멸 작업을 해주어야 하는 경우

        • DB, 파일 및 네트워크 연결과 같은 것은 Unmanaged Resource 리소스 해제 시

        • IDisposable interfaceDispose() 사용

 

  • Garbage Collector

    • garbage

      • new 연산자를 통해 객체를 생성(managed heap)하여 사용하다가 해제된 메모리 공간

    • garbage collector

      • garbage collector는 managed heap이 부족하다고 판단되는 시점에 불필요한 객체의 Finalize()를 호출하여 객체를 소멸시키는 작업을 수행

    • 강제적인 garbage collector 작동

      • System namespace의 GC Class에 있는 Collect() method를 호출하여 garbage collector를 강제적으로 작동 시킬 수 있다.

      • 시스템에 성능 저하를 유발할 수 있어 불가피한 상황이 아니라면 강제 호출은 피해야 한다.

        • 예) 대용량의 객체를 사용한 뒤 시스템 부하를 줄여야 하는 상황

 

  • Gabarge Collection과 Generations

    • 생성된지 오래된 객체와 최근에 생성된 객체를 비교할 때 오래된 객체가 더 오랫동안 heap 영역에 남을 가능성이 높다.

      • Main()에 생성된 객체와 다른 method에서 생성된 객체를 비교

    • 0세대 : 최근에 생성된 객체, 단 한번도 garbage collection에 mark된 적이 없는 것

    • 1세대 : garbage collection이 mark했으나 아직 살아있는 객체, 즉 heap에 여유공간이 많아 제거하지 않은 객체

    • 2세대 : garbage collection이 mark한 후 , 한번 체크하고 갔지만 아직 살아있는 객체

    • garbage collection이 일어나면

      • 먼저 0세대에 해당하는 객체들을 mark하고 리소스 해제, 남은 객체는 다음 세대로 바꿈

      • 0세대 객체를 해제한 뒤에도 heap이 부족하면 1세대 객체도 mark후 해제

      • 그래도 부족하면 2세대도 mark 후 해제

 

  • System.GC class member

    • Collect()

      • GC가 heap에 있는 객체에 대해 FInalize()를 호출하게 함

      • 또한 특정 세대의 객체를 해제

    • GetGeneration()

      • 객체가 현재 속해있는 세대를 리턴

    • MaxGeneration

      • 시스템에 있는 2세대(최종 세대)를 리턴

    • ReRegisterForFinalize()

      • 현재 객체가 Finalize()를 호출하지 못하도록 되어 종료될 수 없을 때 종료 가능(finalizable) 상태로 재 등록

    • SupperessFinalize()

      • 현재 객체의 Finalize()를 호출하지 못하도록 설정

    • GetTotalMemory()

      • heap 영역의 사용중인 전체 memory를 리턴(byte 단위)

 

  • 소멸자(destructor)

    • new 연산자를 사용하여 객체를 생성하면 managed heap이라는 영역에 할당한다. 그 뒤

    • .NET Runtime은 자동적으로 Finalize() method를 지원하는가(소멸자가 구현되었는가)를 체크

    • 지원할 경우, 해당 객체의 reference를 finalization queue에 저장

    • GC가 garbage collection을 수행할 때 이 queue에 있는 객체들부터 처리하기 위해 소멸자를 호출

    • 때문에 소멸자만 믿고 기다리는 것은 좋은 방법이 아님

      • 더욱이 lock과 관련있는 작업이라면...

    • 소멸자는 Compile되면 Finalize()로 변환된다

    • Finalize()는 명시적으로 호출할 수 없기 때문에 소멸자를 사용해야 한다.

 class AnyClass{

          ~AnyClass(){

                          // 정리작업 수행

          }

}

 

 

 

 protected override void Finalize(){

            try{

                        // 정리작업 수행

            }

            finally{

                        base.Finalize();

            }

}

 

 

  • IDisposable interface와 Dispose()

    • GC는 관리되는 객체가 더 이상 사용되지 않을 경우 해당 객체에 할당된 리소스를 자동으로 해제하지만 garbage collection이 언제 발생할 지 예측할 수 없다

    • DIspose()는 코드내에서 리소스를 해제하도록 명시하는 방법

    • 객체가 더 이상 사용되지 않는 시점에 바로 리소스가 해제됨

    • Dispose()는 해당 객체의 GC.SuppressFinalize 메소드를 호출해야 한다

      • GC가 자동으로 호출하는 Finalize()는 리소스를 많이 소모하기 때문에 Dispose()를 통해 개체가 이미 정리된 경우라면 GC에서 개체의 Finalize 메소르드를 호출할 필요가 없다.

      • 현재 finalization queue에 있는 경우(소멸자가 구현된 경우) GC.SupperessFinalize()는 GC에 의해 Finalize 메소드가 호출되는 것을 억제

    • DIspose()를 구현할 때

      • class에 포함된 모든 리소스는 물론,

      • 상속 받았다면 base class의 Dispose()도 호출하여

      • 해당 base class의 모든 리소스도 해제해 주도록 한다.

 

[첨부 : 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌



 
  • Exception(예외 처리)
    • Exception : Application이 실행중일 때 발생하는 오류를 처리하는 것
    • .NET에서 제공하는 구조화된 예외처리 방법
    • .NET에서 exception은 하나의 object
    • exception은 어떤 비정상적인 error 상황이 발생되었을 때, 그 문제에 대한 정보를 제공하는 객체
    • system이나 사용자가 정의한 모든 exception은 System.Exception에서 파생된 것


  • System.Exception class member property
    • HelpLink
      • 현재 예외와 관련된 도움말 파일에 대한 링크를 설정하거나 리턴
    • Message
      • 현재 발생한 Exception을 설명하는 text를 리턴
    • Source
      • Exception을 발생시킨 application이나 객체 이름을 설정하거나 리턴
    • StackTrace
      • Exception을 발생한 method의 stack 상세 정보를 리턴
    • TargetSite
      • Exception을 발생시킨 method name을 리턴
    • InnerException
      • 현재 예외를 발생시키는 Exception의 인스턴스를 리턴

 

  • try, catch, finnaly 개요
    • try : 프로그램이 수행되는 일반적인 코드
    • catch : exception 발생시 처리하는 코드
    • finally : 리소스를 해제하는 것과 같이 exception 발생 유무를 떠나 수행되어야 하는 코드

 

       

      try{

               // 일반 코드, exception 발생 가능성이 있는 코드

      }

       

      catch{

               // exception 발생시 처리되어야 하는 코드

      }

       

      finally{

               // exception 발생 유무와 상관 없이 수행되어야 하는 코드

      }

       

 

  • catch
    • 중첩된 exception 처리기를 지정할 수 있다.
    • 이때 지정된 순서대로 exception 처리기를 찾아 자신에 알맞는 처리기를 수행하고 더이상의 처리기를 찾지 않는다.
    • 때문에 catch를 다중으로 정의할 때, 상세한 것을 처리하는 처리기를 먼저 지정하고, 보다 일반적인 처리기는 뒤에 지정한다.
       

      catch(IndexOutofRangeException e){

                       // 배열 첨자가 넘어섰을 때 Exception 처리

      }

      catch(FormatException e){

                       // 형변환 오류시 Exception 처리

      }

      catch(Exception e){

                       // 일반 예외 처리

      }

      catch{

                       // C++ 등 Exception이 관리되지 않는 라이브러리에서 발생된 것 처리 

      }

 

 

  • 중첩된 try catch finally 구문
     

    try{

           // A : F, G 수행

           try{

                     // B -> 안쪽 Catch에서 exception 처리기를 찾아 실행, 안쪽에 처리기가 없다면 안쪽 finally를 수행하고,

                                 바깥쪽 catch에서 exception 처리기를 찾음. 이 때, E부분은 수행되지 않음.

           }

            catch(FormatException e){

                     // C -> 안쪽 finally를 수행하고, 바깥쪽 catch에서 exception 처리기를 찾음. 이 때, E 부분은 수행되지 않음.

           }

            finally{

                     // D -> 바깥쪽 catch 에서 exception 처리기를 찾음. 이 때, E 부분은 수행되지 않음

           }

            // E : F, G 수행

    }

    catch(Exception e){ // F 예외처리      }

    finally{ // G 정리작업                        }

 

 

  • custom exception
    • 별도의 class에 처리되기 원하는 예외 상황에 대한 상세하게 캡슐화하는 것
    • System.Exception class에서 파생
    • custom exception class내에 catch 블록에서 사용할 member field나 method를 정의하거나 overridding
    • 단순히 base class의 member를 호출하여 정의할 수도 있음

 

  • throw exception
    • 코드가 실행중일 때 일정한 조건을 충족하지 않는 경우에 throw 문을 통해 원하는 타입의 예외를 발생시킬 수 있다.
    • throw 키워드 뒤에 해당하는 exception의 instance를 생성하면 된다.

   throw new IndexOutOfRangeException("배열 첨자가 잘못되었습니다.");

 


출 처 : (주) 인터데브 솔루션 개발 사업부 박준호님 C# 동영상 강좌

박준호님의 C# 강좌 - 이벤트(Event)

프로그램&DB/C# 2009. 4. 14. 17:09 Posted by Josep.H.S
  • Event
    • 어떤 사건이 발생했을 때 Application에 통보하는 방법
      • 이벤트 발생기(publisher) : 이벤트 발생시 다른 객체에 이벤트 발생을 통보하는 일을 담당하는 객체
      • 이벤트 처리기(Subscriber) : 이벤트 발생시 실제 호출될 method(이벤트 핸들러)가 등록된 객체

 

  • Event 선언
    • Event와 함께 사용될 delegate의 정의 확인
      • delegate는 호출할 method의 형식만 정의한 것이기 때문에 해당 method의 형식이 이미 지정된 delegate가 있다면 그대로 사용이 가능하다

public delegate void AnyEventHandler(object sender, EventArgs e);

 

    • event 키워드를 사용하여 class에 event member 정의
      • public, protected, private, internal 등의 접근제한자와 static, new 등의 키워드

class MyClass{

         public event AnyEventHandler MyEvent;

}

  • Event 호출
    • class에 event를 선언하면 해당 event를 지정된 delegate 형식의 member field처럼 사용 가능
    • 이 class의 객체를 생성하는 클라이언트가 delegate를 event에 연결하지 않았으면 event는 Null이 된다.
    • delegate를 event에 연결하였다면 delegate를 참조하게 된다. 따라서 event 호출은 일반적으로 우선 Null인지 확인한 다음 event를 호출하여 실행

protected virtual void AnyMethod(EventArgs e){

        if(MyEvent != null)

                MyEvent(this, e);

}

    • event는 해당 event를 선언한 class에서만 호출 가능

 

  • Event 연결
    • event를 선언한 class 밖에서 event는 emmber field처럼 보이지만 할 수 있는 작업은 delegate를 추가하거나 제거하는 일만 가능하다
      • delegate 추가

anyobject.MyEvent += new AnyEventHandler(CalledMethod);

      • delegate 제거

anyobject.MyEvent -= new AnyEventHandler(CalledMethod);

 

  • Event와 Delegate
    • Event를 발생시키는 코드는 delegate instance를 호출하는 것과 동일
    • event member가 정의된 class를 사용하는 측에서 이 class의 instance가 발생하는 event를 받기 위해서는 delegate instance를 생성하고 event member에 delegate instance를 추가해야 한다.

 

  • Event guideline
    • Event Handler(이벤트 발생시 호출되는 method)는 .NET의 event guideline에 따라 아래의 두개의 parameter를 받는 메쏘드로 정의 된다.
      • object class type parameter sender
        • 동일한 Event Handler가 복수의 이벤트 발생기에 등록되어 질 수 있으므로 sender는 일반적으로 Event를 발생한 이벤트 발생기 객체에 대한 참조를 포함한다.
      • EventArgs class의 sub class type parameter e
        • 이벤트 발생기로부터 Event Handler로 전달할 부가적인 정보

void Onclick(object sender, EventArgs e){

          // 이벤트를 처리하는 코드

}

 

 

[파일 첨부 : 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌


 

박준호님의 C# 강좌 - Delegate

프로그램&DB/C# 2009. 4. 14. 17:06 Posted by Josep.H.S
  • Delegate
    • 한 객체의 Method에서 자기를 생성한 객체의 함수를 호출해야 할 필요가 있을 때 사용
      • 한 시스템에 있는 객체가 다른 객체를 생성해서 그것을 사용하고, 또 그 생성된 객체가 자기를 생성한 객체의 함수를 호출하는 형태의 '양방향 호출'
      • Windows API의 Callback function(콜백 함수)를 생성하기 위한 function point 기능을 더 안정적으로 확장
    • event와 함께 사용되어 .NET Framework에서 event 처리에 많이 사용
    • 일반적인 method와 달리 compile 시에는 매개변수로 전달되는 method가 무엇인지   알지 못한다.


  • Delegate의 정의
    • 현재 정의 하는 delegate가 어떤 종류의 method를 나타내는지 compiler에게 알려주는 것을 의미
    • delegate를 정의할 때는 delegate가 나타내고자 하는 method의 signature의 완전한 사항을 명시해야 한다.
    • public, private, protected 접근자 사용 가능

                   delegate void OneOperation(uint x);

                   //하나의 uint parameter를 가지고 void를 반환하는 method의 delegate

                  

                   delegate double TwoOperation(long L1, long L2);

                   //두 개의 long을 parameter로 받아들이고 double을 반환하는 method의 delegate

 

                   public delegate string ThreeOperation();

                   // parameter가 없으며 string을 반환하는 method의 delegate

 

  • Delegate의 instance 생성 및 사용
    • new 연산자를 통해 delegate의 instance를 생성
    • 이 instance를 통해 method를 호출

       delegate void MyDelegate(string s); // delegate 정의

       public static void Hello(string s){ .....} // delegate가 호출할 method

       MyDelegate md = new MyDelegate(Hello); // delegate instance 생성

       md("Hello World~!") // delegate instance를 통해 Hello Method를 호출

 

       delegate int MyDelegate(string s); // delegate 정의

       public static int IntVal(string s){return 123;} // delegate가 호출할 method

       MyDelegate md  = new MyDelegate(IntVal); // delegate instance 생성

       int a = md("Hello World~!"); // delegate instance를 통해 Hello method를 호출

 

  • Multicast Delegate
    • delegate를 통해 두 개 이상의 method를 호출하는 것
    • 유의 : return 값에 있어서
      • Multicast delegate를 구현한다는 것은 한번의 호출로 두 개 이상의 method를 실행하는 것인데, 그 호출의 return 값이 여러개라면 어떤 값을 받을것인가?
      • 마지막 return 값 이외에는 리턴받을 수 없다.
    • Event 처리와 함께 주료 사용됨

delegate void MyDelegate(string s); // delegate 정의

public static void Hello(string s){.....} // delegate가 호출할 method 1

public static void Process(string s){....} // delegate가 호출할 method 2

MyDelegate md = new MyDelegate(Hello); // 첫번째 호출될 method 생성

md += new MyDelegate(Process); // 두번째 호출될 method 지정

md("Hello World~!"); // delegate instance를 통해 Hello Method를 호출

 

 

첨부 : 해당 강좌 소스파일

출 처 : (주) 인터데브 솔루션 개발 사업부 박준호님 C# 동영상 강좌




  • Collection
    •  배열의 경우 인덱스를 사용하여 각 항목(element)에 접근하게 되는데, Collection은 인덱스를 사용하지 않고 모든 element에 순차적으로 접근할 수 있는 방법을 제공한다.
    •  각 element에 순차적으로 접근할 수 있도록 허용하는 객체의 집합니다.
    •  객체가 열거자(enumerator)라고 불리는 객체의 참조를 제공하면 collection이라 한다.
    •  열거자는 Collection 내의 항목을 순차적으로 엑세스 할 수 있다.
    •  foreach를 통해 객체의 내에 순차적으로 접근 할 수 있도록 기능을 제공한다.

 

  •  Collection의 동작
    • Collection이 foreach와 함께 사용될 때 foreach는 collectionm의 Ienumrable interface로 부터 GetEnumerator() method를 호출
    • GetEnumerator()는 IEnumerator interface를 구현한 열거자 객체(enumerator object)를 return
    • foreach는 이 열거자 객체로부터 IEnumerator interface를 얻어 method(MoveNext(), Reset())와 property(Current)를 호출

 

  • Custom Collection
    • collection을 만드려면 System.Collections namespace의 IEnumrable interface를 구현해야 한다.

    interface IEnumrable{

IEnumerator GetEnumerator(); // 열거자 객체를 반환

    }

    •  열거자 객체는 System.Collections의 IEnumerator를 구현한다.

  interface IEnumrator{

object Curren{get;}

bool MoveNext();

void Reset();

  }

 

    •   IEnumerator를 구현한 Class의 객체는 다음과 같이 작동을 구현
      •    객체 초기화시 어떤 element도 가리키지 않음
      •    MoveNext method를 호출하여 첫번째 element로 이동한다.
      •    Current property를 통해 element를 뽑아낸다.
      •    MoveNExt를 호출하여 다음 element로 이동
      •    위 과정을 마지막까지 반복
      •    Current property가 null을 return하면 더이상 접근할 항목이 없다는 의미
      •    Reset method를 호출하여 처음으로 돌아가거나, 처리 종료
      •    Reset 호출시에는 첫번째 element의 이전을 가리키므로 MoveNext

 

  • ArrayList
    • 객체를 배열로 만들어 사용하는데 유용한 기능을 제공
    • 확장성이 뛰어나 삽입/삭제/열거 등의 기능을 제공할 수 있다.
    • 배열의 크기를 초기에 지정할 수 있다.
    • 정의된 크기를 초과하면 자동으로 크기를 늘려준다.
    •  ArrayList와 Collection의 관계
      • ArrayList는 IEnumerable interface를 상속받는다.
      • 때문에 ArrayList의 GetEnumerator를 통해 열거자 객체를 얻을 수 있다.
      • 이를 통해 순차적으로 ArrayList에 접근할 수 있다.
    • 생성 및 초기화
      •    ArrayList myAL = new ArrayList(); // ArrayList 생성
      •    myAL.add(new car("그랜저", 100000)); //초기화
      •    myAL.add(new car("체어맨", 200000));
      •    myAL.add(new car("포텐샤", 300000));
    • ArrayList 정보

   myAL.Count; // 실제로 저장된 element의 수

   int MaxSize = myAL.Capacity; //현재 ArrayList 총 크기 얻기

   myAL.Capacity = 20; // 저장될 수 있는 총 용량 설정(Default는 16)

    • element 제거

   myAL.RemoveAt(1); // 0부터 시작해서 지정된 요소를 제거

 

    • ArrayList를 배열로 변환
      • parameter로 배열을 전달해야 하는 경우 사용(Type 변환 주의)

   Car[] CarArray = new Car[myAl.Count]; // 저장할 배열 생성

   for(int i=0; i<myAL.count; i++){

           CarArray[i] = (Car)myAL[i];

   }

   foreach(Car i in CarArray){

           Console.WriteLine("차종 : {0}, 가격 : {1}", i.carName, i.carPrice);

   }

 

  • HashTable
    • 특정 Key 값에 의해 element에 접근할 수 있도록 고안된 데이터 구조
    • 어떠한 형태의 객체이든 저장 가능

  Hashtable hash1 = new Hashtable(); // HashTable 객체 선언

 

  hash1.Add("690810", "홍길동");

  hash1.Add("701116", "박길동");

  hash1.Add("740210", "김길동");

  hash1.Add("720929", "이길동");

 

  foreach(string item1 in hash1.Keys) {  // key data type에 의한 foreach 출력

           Console.WriteLine(item1 + "       " + hash1[item1]);

  }

 

[파일첨부 : 해당 소스 파일]

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌

박준호님의 C# 강좌 - Namespace

프로그램&DB/C# 2009. 4. 14. 16:59 Posted by Josep.H.S
  • Namespace

    • class와 각종 data type들을 그 연관성에 따라 그룹화시키는 논리적인 개념

    • Namespace를 중첩시켜 계층적인 data type을 구성

    • class의 이름 충돌을 해결하기 위한 용도로 사용

    • Namespace를 사용할 경우 이름이 길어지게 되는데, 이것을 해결하기 위해 Namespace Alias를 통해 Namespace의 별칭을 지정할 수 있다.

    • namespace에 포함될 수 있는 것

      • namespace, class, interface, struct, enum, delegate

 

  • Namespace의 범위

    • class는 그 class가 참조될 수 있는 범위를 가지고 있다.

    • namespace가 지정되지 않으면 같은 namespace에서 처리

 using System;

 class Utility{          // 이 두개의 class는 default namespace에 속한다.

          public void DisplayString(){  Console.WriteLine("Hello")};

 }

 

 class Myclass{

          public static void Main(){

                     Utility util = new Utility();

                     util.DisplayString();

 

                     System.Threading.Thread.Sleep(100000); // 다른 namespace class

          }

}

 

  • class 이름이 중복될 때

    • Application은 수많은 class들로 이루어지고, class의 이름이 중복되는 상황이 발생 할 수 있다.

    • namespace를 사용하지 않는다면, class의 이름을 서로 다르게 지정할 수 밖에 없다.

 public class Project1Utility{

             .............

 }

 

 public class Project2Utility{

             .............

 }

 

 // 복잡한 이름으로 사용이 불편

 namespace MyCompany.Project1{

             public class Utility{

             }

 }

 

namespace MyCompany.Project2{

             public class Utility{

             }

}

 

  • 단일 Namespace의 선언 및 사용

 namespace Project1{

             public class Utility{

                         public void DisplayString(string srt) {  ........ } ;

             }

}

 using Project1;

 namespace Project2{

             public class MyClass{

                          public static void Main(){

                                       Utility util1 = new Utility();  // using 키워드를 사용한 참조

                                       Project1.Utility util2 = new Project1.Utility();

                                       util1.DisplayString("Hello World~!");

                          }

             }

}

 

  • 중첩된 Namespace의 선언

 namespace MyCompany

                namespace Project1{

                             public class Utility{

                             }

                }

 }

                                                                               

 namespace MyCompony

                namespace Project2{

                             public class Utility{

                             }

                }

 }

 namespace MyCompany.Project1{

                 public class Utility{

                 }

 }

 

 namespace MyCompany.Project2{

                 public class Utility{

                 }

 }

 

 

 

 

 

 

  • Namespace의 사용과 Alias

 using MyCompany.Project1;

 

 // ....

 Utility util1  = new Utility(); // using 키워드를 사용한 참조

 MyCompany.Project1.Utility util2 = new MyCompony.Project1.Utility();

 System.Threading.Thread.Sleep(100000);

 using A1 = MyCompany.Project1; // namespace alias 정의

 

 // ....

 A1.Utility util2 = new A1.Utility(); // namespace alias 사용

 

 

[첨부 파일 : 소스 파일]

 

출처 : (주)인터데브 솔루션 개발 사업부 박준호님의 C# 동영상 강좌