Delphi and Unicode

Similar documents
JAVA PROGRAMMING 실습 08.다형성

PowerPoint Presentation

PowerPoint Template

슬라이드 1

PowerPoint Presentation

아이콘의 정의 본 사용자 설명서에서는 다음 아이콘을 사용합니다. 참고 참고는 발생할 수 있는 상황에 대처하는 방법을 알려 주거나 다른 기능과 함께 작동하는 방법에 대한 요령을 제공합니다. 상표 Brother 로고는 Brother Industries, Ltd.의 등록 상

Microsoft PowerPoint - chap02-C프로그램시작하기.pptx

1. auto_ptr 다음프로그램의문제점은무엇인가? void func(void) int *p = new int; cout << " 양수입력 : "; cin >> *p; if (*p <= 0) cout << " 양수를입력해야합니다 " << endl; return; 동적할

A Tour of Java V

Microsoft PowerPoint - CSharp-10-예외처리

gnu-lee-oop-kor-lec06-3-chap7

금오공대 컴퓨터공학전공 강의자료

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

Microsoft PowerPoint - chap06-2pointer.ppt

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

Visual Basic 반복문

ThisJava ..

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Microsoft PowerPoint - chap01-C언어개요.pptx

17장 클래스와 메소드

C++ Programming

Design Issues

학습목표 함수프로시저, 서브프로시저의의미를안다. 매개변수전달방식을학습한다. 함수를이용한프로그래밍한다. 2

쉽게 풀어쓴 C 프로그래밍

예제 2) Test.java class A intvar= 10; void method() class B extends A intvar= 20; 1"); void method() 2"); void method1() public class Test 3"); args) A

C# Programming Guide - Types

MVVM 패턴의 이해

View Licenses and Services (customer)

JAVA PROGRAMMING 실습 02. 표준 입출력

PowerPoint Presentation

Microsoft Word - PLC제어응용-2차시.doc

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

Microsoft PowerPoint - additional01.ppt [호환 모드]

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

. 스레드 (Thread) 란? 스레드를설명하기전에이글에서언급되는용어들에대하여알아보도록하겠습니다. - 응용프로그램 ( Application ) 사용자에게특정서비스를제공할목적으로구현된응용프로그램을말합니다. - 컴포넌트 ( component ) 어플리케이션을구성하는기능별요

오버라이딩 (Overriding)

11장 포인터

JVM 메모리구조

API - Notification 메크로를통하여어느특정상황이되었을때 SolidWorks 및보낸경로를통하여알림메시지를보낼수있습니다. 이번기술자료에서는메크로에서이벤트처리기를통하여진행할예정이며, 메크로에서작업을수행하는데유용할것입니다. 알림이벤트핸들러는응용프로그램구현하는데있어

Frama-C/JESSIS 사용법 소개

Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

설계란 무엇인가?

설계란 무엇인가?

Poison null byte Excuse the ads! We need some help to keep our site up. List 1 Conditions 2 Exploit plan 2.1 chunksize(p)!= prev_size (next_chunk(p) 3

<4D F736F F F696E74202D2036C0CFC2B05FB0B4C3BCC1F6C7E2C7C1B7CEB1D7B7A1B9D62E707074>

PowerPoint Presentation

Chapter #01 Subject

PowerPoint Template

<4D F736F F F696E74202D203137C0E55FBFACBDC0B9AEC1A6BCD6B7E7BCC72E707074>

PowerPoint Presentation

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

Microsoft PowerPoint - 2강

Microsoft PowerPoint - lec12 [호환 모드]

This is a title of the whitepaper

Microsoft Word - FunctionCall

vRealize Automation용 VMware Remote Console - VMware

Microsoft PowerPoint - chap10-함수의활용.pptx

Microsoft PowerPoint - C프로그래밍-chap03.ppt [호환 모드]

adfasdfasfdasfasfadf

1. 객체의생성과대입 int 형변수 : 선언과동시에초기화하는방법 (C++) int a = 3; int a(3); // 기본타입역시클래스와같이처리가능 객체의생성 ( 복습 ) class CPoint private : int x, y; public : CPoint(int a

<322EBCF8C8AF28BFACBDC0B9AEC1A6292E687770>

5장. JSP와 Servlet 프로그래밍을 위한 기본 문법(완성-0421).hwp

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

Microsoft PowerPoint - Chapter 6.ppt

No Slide Title

Microsoft PowerPoint - chap03-변수와데이터형.pptx

안드로이드기본 11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 -

PowerPoint 프레젠테이션

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Microsoft PowerPoint - Chap12-OOP.ppt

쉽게

쉽게 풀어쓴 C 프로그래밍

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

Microsoft PowerPoint - ch07 - 포인터 pm0415

OCW_C언어 기초

제이쿼리 (JQuery) 정의 자바스크립트함수를쉽게사용하기위해만든자바스크립트라이브러리. 웹페이지를즉석에서변경하는기능에특화된자바스크립트라이브러리. 사용법 $( 제이쿼리객체 ) 혹은 $( 엘리먼트 ) 참고 ) $() 이기호를제이쿼리래퍼라고한다. 즉, 제이쿼리를호출하는기호

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

윈도우시스템프로그래밍

Slide 1

Chapter 6 Objects and Classes

PowerPoint 프레젠테이션

임베디드시스템설계강의자료 6 system call 2/2 (2014 년도 1 학기 ) 김영진 아주대학교전자공학과

Slide 1

PowerPoint Presentation

Spring Boot/JDBC JdbcTemplate/CRUD 예제

A Dynamic Grid Services Deployment Mechanism for On-Demand Resource Provisioning

제11장 프로세스와 쓰레드

쉽게 풀어쓴 C 프로그래밍

어댑터뷰

Microsoft PowerPoint - e pptx

JAVA PROGRAMMING 실습 05. 객체의 활용

JUNIT 실습및발표

제4장 기본 의미구조 (Basic Semantics)

슬라이드 1

chap 5: Trees

강의 개요

Microsoft Word - java19-1-midterm-answer.doc

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

제8장 자바 GUI 프로그래밍 II

Transcription:

솔루션문서 새 Delphi 코딩스타일과아키텍처 Delphi 2009 의언어기능리뷰 2008 년 12 월 Corporate Headquarters Asia-Pacific Headquarters DEVGEAR 100 California Street, 12th Floor L7. 313 La Trobe Street 서울특별시서초구 San Francisco, California 94111 Melbourne VIC 3000 반포동 743-14 Australia 데브기어 4층

소개 : DELPHI 언어 Object Pascal 로더잘알려진 Delphi 언어는단일상속및개체참조모델이특징인강력한최신타입확인및개체지향언어입니다. 최근몇년간 Delphi 언어는레코드메소드, 레코드를위한운영자오버로드, 클래스데이터, 중첩타입, 봉인된클래스, 최종메소드및기타관련기능등을사용하여향상되었습니다. 가장놀라운확장은새로운메소드를기존클래스에추가하거나일부기존메소드를대체하는데사용하는기술인클래스도우미의도입일것입니다. 그러나 Delphi 2009 에서컴파일러에추가된새기능은훨씬더중요합니다. Unicode 를지원하기위한문자열타입에대한확장이외에도 Delphi 의최근버전에는제네릭데이터타입, 익명메소드및여러개의기타 사소하지만 흥미로운기능이적용되었습니다. 제네릭소개 제네릭클래스의첫예로서저는키 - 값쌍데이터구조를구현했습니다. 아래에표시된첫번째코드조각은값을보유하는데사용되는개체와함께, 일반적으로작성되는데이터구조를보여줍니다. TKeyValue = class private FKey: string; FValue: TObject; procedure SetKey(const Value: string); procedure SetValue(const Value: TObject); public property Key: string read FKey write SetKey; property Value: TObject read FValue write SetValue; 이클래스를사용하려면다음조각에표시된대로개체를생성하고, 해당개체의키와값을설정하여사용할수있습니다. // FormCreate kv := TKeyValue.Create; // Button1Click kv.key := 'mykey'; kv.value := Sender; // Button2Click kv.value := self; // 폼 // Button3Click ShowMessage ('[' + kv.key + ',' + kv.value.classname + ']'); 제네릭을사용하면값에대한폭넓은정의를사용할수있지만그것이핵심은아닙니다. 앞으로다루겠지만큰차이점은키 - 값제네릭클래스를인스턴트화하면해당클래스가지정된데이터타입에연결된특정클래스가된다는것입니다. 이렇게하면코드타입을더안전하게만들수있지만개인적으로는기존에사용하던방식을그대로고수합니다. 이제제네릭클래스를정의하는 2

데사용되는구문에대해알아보도록하겠습니다. TKeyValue<T> = class private FKey: string; FValue: T; procedure SetKey(const Value: string); procedure SetValue(const Value: T); public property Key: string read FKey write SetKey; property Value: T read FValue write SetValue; 이클래스정의에는자리표시자 T 에의해표시되는한개의지정되지않은타입이있습니다. 제네릭 TKeyValue<T> 클래스는지정되지않은해당타입을속성값필드타입과 setter 메소드매개변수로사용합니다. 그러나메소드는일반적인방법으로정의되며, 메소드가제네릭타입과관련이있다하더라도해당정의에는제네릭타입을포함한클래스의전체이름이포함됩니다. procedure TKeyValue<T>.SetKey(const Value: string); FKey := Value; procedure TKeyValue<T>.SetValue(const Value: T); FValue := Value; 대신, 클래스를사용하려면제네릭타입의실제값을제공하여전체클래스를정규화해야합니다. 예를들어이제아래와같이작성하여키 - 값개체호스팅버튼을값으로선언할수있습니다. kv: TKeyValue<TButton>; 또한전체이름이실제타입이름이기때문에인스턴스작성시해당전체이름도필요합니다. ( 인스턴스화되지않은제네릭타입이름은타입구성메커니즘과유사합니다.) 키 - 값쌍에대해특정타입의값을사용하면, TButton 개체또는파생개체를키값쌍에추가할수있고추출된개체의다양한메소드를사용할수있기때문에코드가훨씬강력해집니다. 다음은일부코드조각의예입니다. // FormCreate kv := TKeyValue<TButton>.Create; // Button1Click kv.key := 'mykey'; kv.value := Sender as TButton; // Button2Click kv.value := Sender as TButton; // was "self" // Button3Click ShowMessage ('[' + kv.key + ',' + kv.value.name + ']'); 코드의이전버전에서는제네릭개체할당시버튼또는양식을추가할수있었습니다. 이제는버튼만추가할수있으며, 이것은컴파일러에의해강제로적용된규칙입니다. 마찬가지로, 출력에는제네릭 kv.value.classname 이아니라구성요소이름또는 TButton 의다른속성을사용할수있습니다. 3

물론키 - 값쌍을다음과같이선언하여원본프로그램을모방할수도있습니다. kvo: TKeyValue<TObject>; 제네릭키 - 값쌍클래스의이번버전에서는개체를값으로추가할수있습니다. 그러나추출한개체를특정타입에캐스트하지않으면추출한개체를많이활용할수없습니다. 균형을잘맞추려면다음과같이특정버튼과개체중간의어떤것을찾고값이구성요소가되도록요청할수있습니다. kvc: TKeyValue<TComponent>; 마지막으로다음과같이개체값이아니라보다일반적인정수값을저장하는제네릭키 - 값쌍클래스의인스턴스를생성할수있습니다. kvi: TKeyValue<Integer>; 제네릭의타입규칙 제네릭타입의인스턴스를선언하면이타입은수반되는모든작업에서컴파일러가강제로적용하는특정버전을사용하게됩니다. 따라서, 다음과같은제네릭클래스를가지는경우 TSimpleGeneric<T> = class Value: T; 지정된타입으로특정개체를선언하기때문에다른타입을값필드에할당할수없습니다. 다음두개의개체가지정되면아래의일부할당은틀릴수있습니다. sg1: TSimpleGeneric<string>; sg2: TSimpleGeneric<Integer>; sg1 := TSimpleGeneric<string>.Create; sg2 := TSimpleGeneric<Integer>.Create; sg1.value := 'foo'; sg1.value := 10; // Error // E2010 Incompatible s: 'string' and 'Integer' sg2.value := 'foo'; // Error // E2010 Incompatible s: 'Integer' and 'string' sg2.value := 10; 특정타입을제네릭선언으로정의하면 Object Pascal 과같이강력한타입의언어에서기대하는바처럼컴파일러가강제로적용하게됩니다. 타입확인도전체적으로제네릭개체에적용할수있습니다. 개체에대한제네릭매개변수를지정하면다른호환되지않는타입인스턴스에기반한유사제네릭타입을개체에할당할수없습니다. 잘이해가안되는경우아래예를보면명확하게이해할수있습니다. sg1 := TSimpleGeneric<Integer>.Create; // 에러 // E2010 Incompatible s: // 'TSimpleGeneric<System.string>' // and 'TSimpleGeneric<System.Integer>' 타입호환성규칙은타입이름이아니라구조별로정해지지만제네릭타입인스턴스에다른 4

호환되지않는타입인스턴스를할당할수는없습니다. DELPHI 의제네릭 앞의예에서는 Delphi 3 이인터페이스를도입한이후 Object Pascal 언어로의가장중요한확장중하나인제네릭클래스를정의하고사용하는방법을살펴보았습니다. 이제꽤복잡하지만매우중요한그기술을심도있게다루기전에예를통해그기능을설명하도록하겠습니다. 언어적인측면에서제네릭을설명한다음이기술을언어에추가한주요이유중하나인제네릭컨테이너클래스의사용과정의를포함한추가예로다시돌아가도록하겠습니다. Delphi 2009 에서클래스를정의할때아래와같이꺽쇠괄호내의기타 매개변수 를추가하여이후에제공되는타입의위치를유지할수있다는것을이미살펴봤습니다. TMyClass <T> = class... 제네릭타입은필드타입 ( 앞의예에서사용함 ), 속성의타입, 함수의매개변수또는반환값의타입및기타타입으로사용할수있습니다. 제네릭타입이결과즉매개변수로서만사용되거나클래스의선언이아닌일부메소드의정의에만사용되는경우가있으므로로컬필드 ( 또는배열 ) 에대한타입을반드시사용해야하는것은아닙니다. 확장또는제네릭타입선언의이형식을클래스및레코드에사용할수있습니다. ( 최신버전의 Delphi 에서는레코드도메소드와오버로드된연산자를포함할수있습니다.) C++ 과달리제네릭글로벌함수를선언할수는없지만단일클래스메소드로제네릭클래스를선언할수는있으며이는거의같습니다. 다른정적언어와마찬가지로 Delphi 의제네릭구현은런타임프레임워크에기반하지않고컴파일러와링커로처리되기때문에런타임메커니즘과는거의무관합니다. 런타임시바인딩되는가상함수호출과달리템플릿메소드는사용자가인스턴스화하는각템플릿타입별로한번생성되며컴파일시간동안생성됩니다. 이러한접근방법에는단점도있지만긍정적인측면에서보면제네릭클래스가일반클래스만큼또는런타임범주에대한필요성을줄일수있을정도로보다효율적이라는것을의미합니다. 제네릭타입함수 지금까지살펴본제네릭타입정의의가장큰문제는제네릭타입의개체에대해할수있는작업이거의없다는것입니다. 이러한한계를극복하기위해사용할수있는두가지의기술이있습니다. 첫번째는제네릭타입을특별히지원하는런타임라이브러리의일부특수함수를활용하는것입니다. 두번째는훨씬더강력한방법으로서사용할수있는타입에제약조건을포함한제네릭클래스를정의하는것입니다. 이섹션에서는첫번째부분에, 다음섹션에서는제약조건에초점을맞춰설명하도록하겠습니다. 5

이미설명한바와같이제네릭타입정의의매개변수타입 (T) 에서동작하도록특별히수정된 2 개의기존함수와 1 개의새로운함수가있습니다. Default(T) 는새로운함수로현재타입에대해빈또는 0( 영 ) 인값 이나 null 값을반환하며, 0( 영 ), 빈문자열, nil 등의값이될수있습니다. TypeInfo(T) 는제네릭타입의현재버전에대한런타임정보에포인터를반환합니다. SizeOf(T) 는타입의메모리크기를바이트로반환합니다. 다음예는활성중인 3 개의제네릭타입함수를표시하는제네릭클래스입니다. TSampleClass <T> = class private data: T; public procedure Zero; function GetDataSize: Integer; function GetDataName: string; function TSampleClass<T>.GetDataSize: Integer; Result := SizeOf (T); function TSampleClass<T>.GetDataName: string; Result := GetTypeName (TypeInfo (T)); procedure TSampleClass<T>.Zero; data := Default (T); GetDataName method 에서저는직접데이터구조에액세스하지않고 GetTypeName function( 또는 TypInfo 단위 ) 를사용했습니다. 이방법을사용하면타입이름이있는인코딩된 ShortString 값에서적합한 UTF-8 변환을실행할수있습니다. 위에나온선언이제공된경우 3 개의다른제네릭타입인스턴스에서자체적으로 3 번반복되는다음의테스트코드를컴파일할수있습니다. 여기서는반복된코드를생략했지만데이터필드에액세스하는데사용되는명령문은실제타입에따라달라지므로남겨두었습니다. t1: TSampleClass<Integer>; t2: TSampleClass<string>; t3: TSampleClass<double>; t1 := TSampleClass<Integer>.Create; t1.zero; Log ('TSampleClass<Integer>'); Log ('data: ' + IntToStr (t1.data)); Log (': ' + t1.getdataname); Log ('size: ' + IntToStr (t1.getdatasize)); t2 := TSampleClass<string>.Create; 6

... Log ('data: ' + t2.data); t3 := TSampleClass<double>.Create;... Log ('data: ' + FloatToStr (t3.data)); 이코드를실행하면다음과같은출력이생성됩니다. TSampleClass<Integer> data: 0 : Integer size: 4 TSampleClass<string> data: : string size: 4 TSampleClass<double> data: 0 : Double size: 8 이상하게들리겠지만제네릭클래스내용이외의특정타입에서도제네릭타입함수를사용할수있습니다. 예를들어다음과같이작성할수있습니다. I: Integer; s: string; I := Default (Integer); Log ('Default Integer': + IntToStr (I)); s := Default (string); Log ('Default String': + s); Log ('TypeInfo String': + GetTypeName (TypeInfo (string)); Default are 에대한호출은 Delphi 2009 의새로운기능이지만 (( 템플릿외에서는전혀유용하지않음 ) 마지막의 TypeInfo 에대한호출은이전버전의 Delphi 에서이미가능했습니다. 다음은호출에대한간단한출력입니다. Default Integer: 0 Default String: TypeInfo String: string 제네릭제약조건 위에서살펴본바와같이제네릭타입값을통해제네릭클래스의메소드로할수있는작업은매우제한되어있습니다. 제네릭타입값을차례로분배 ( 즉, 할당 ) 하고위에서방금전에설명한제네릭타입함수가허용하는제한된작업을수행할수있습니다. 제네릭타입클래스의실제작업중일부를수행하기위해서일반적으로제약조건을배치합니다. 예를들어제네릭타입을클래스로제한하면컴파일러를사용하여클래스의모든 TObject 메소드를호출할수있습니다. 클래스를지정된계층에속하도록하거나특정인터페이스를실행하도록제약할수있습니다. 7

클래스제약조건 사용할수있는가장간단한제약조건은클래스제약조건입니다. 클래스제약조건을사용하려면다음과같은제네릭타입을선언해야합니다. TSampleClass <T: class> = class 클래스제약조건을지정하여개체타입만제네릭타입으로사용할수있음을지정합니다. 다음의선언을사용하여클래스제약조건을실행할수있습니다. TSampleClass <T: class> = class private data: T; public procedure One; function ReadT: T; procedure SetT (t: T); 다음에표시된처음 2 개의인스턴스 (3 번째는아님 ) 를생성할수있습니다. sample1: TSampleClass<TButton>; sample2: TSampleClass<TStrings>; sample3: TSampleClass<Integer>; // Error 이마지막선언으로발생하는컴파일러에러는다음과같습니다. E2511 Type parameter 'T' must be a class 이제약조건을지정하면어떤이점이있을까요? 제네릭클래스메소드에서이제가상메소드를포함한 TObject 메소드를호출할수있습니다! 다음은 TSampleClass 클래스에대한 One 메소드입니다. procedure TSampleClass<T>.One; if Assigned (data) then Form30.Log('ClassName: ' + data.classname); Form30.Log('Size: ' + IntToStr (data.instancesize)); Form30.Log('ToString: ' + data.tostring); 프로그램을사용하여다음코드조각에서처럼 One 메소드가제네릭타입의몇몇인스턴스를정의하고사용할때의실제효과를확인할수있습니다. sample1: TSampleClass<TButton>; sample1 := TSampleClass<TButton>.Create; try sample1.sett (Sender as TButton); sample1.one; finally sample1.free; 8

사용자정의된 ToString 메소드를포함한클래스를선언하면제네릭타입에제공된실제타입과상관없이데이터개체가특정타입에속할경우이사용자정의버전이호출됩니다. 다시말하면다음과같은 TButton descendant 가있는경우, TMyButton = class(tbutton) public function ToString: string; override; 이개체를 TSampleClass<TButton> 값으로전달하거나제네릭타입의특정인스턴스를정의할수있으며, 두경우모두 One 을호출하면다음과같이 ToString 의특정버전을실행하게됩니다. sample1: TSampleClass<TButton>; sample2: TSampleClass<TMyButton>; mb: TMyButton;... sample1.sett(mb); sample1.one; sample2.sett(mb); sample2.one; 클래스제약조건과유사하게다음과같이선언한레코드제약조건을사용할수있습니다. TSampleRec <T: record> = class 그러나일반적으로서로다른레코드가공통으로가지는것이거의없기때문에 ( 공통조상이없음 ), 이선언은다소제한됩니다. 특정클래스제약조건 제네릭클래스가클래스의특정하위세트 ( 특정계층 ) 과함께동작해야하는경우지정된기본클래스에기반한제약조건을지정해야할수도있습니다. 예를들어다음과같이선언하는경우 TCompClass <T: TComponent> = class 이제네릭클래스의인스턴스는구성요소클래스, 즉 Tcomponent 하위항목클래스에만적용할수있습니다. 이렇게하면매우특정적인제네릭타입 ( 다소이상하게들리겠지만실제로그러함 ) 을사용할수있으며컴파일러를사용하여해당제네릭타입에서작업하는동안 TComponent 클래스의모든메소드를사용할수있습니다. 이메소드가매우강력해보인다면다시한번생각해봐야합니다. 상속과타입호환규칙으로할수있는작업에대해고려한다면제네릭클래스를사용하지않고도일반적인개체지향기술을사용하여동일한문제를해결할수있습니다. 특정클래스제약조건이전혀유용하지않다고말하는것은아니지만높은수준의클래스제약조건이나개인적으로매우흥미롭게생각한인터페이스기반제약조건만큼강력하지는않습니다. 9

인터페이스제약조건 제네릭클래스를지정된클래스로제약하는대신지정된인터페이스를타입매개변수로서구현하는클래스만수락하는것이일반적으로보다나은유연성을제공합니다. 그렇게하면제네릭타입의인스턴스에서인터페이스를호출할수있습니다. 이미말했듯이제네릭에대한인터페이스제약조건의사용은.NET 프레임워크에서매우일반적입니다. 예를통해인터페이스제약조건의사용을알아보도록하겠습니다. 먼저다음과같이인터페이스를선언해야합니다. IGetValue = interface ['{60700EC4-2CDA-4CD1-A1A2-07973D9D2444}'] function GetValue: Integer; procedure SetValue (Value: Integer); property Value: Integer read GetValue write SetValue; 그런다음인터페이스를구현하는클래스를정의할수있습니다. TGetValue = class(tsingletonimplementation, IGetValue) private fvalue: Integer; public constructor Create (Value: Integer = 0); function GetValue: Integer; procedure SetValue (Value: Integer); 다음과같이제네릭클래스를지정된인터페이스를구현하는타입으로정의하면흥미로운일이일어납니다. TInftClass <T: IGetValue> = class private val1, val2: T; // or IGetValue public procedure Set1 (val: T); procedure Set2 (val: T); function GetMin: Integer; function GetAverage: Integer; procedure IncreaseByTen; 이클래스의제네릭메소드에대한코드에다음과같이작성할수있습니다. function TInftClass<T>.GetMin: Integer; Result := min(val1.getvalue, val2.getvalue); procedure TInftClass<T>.IncreaseByTen; val1.setvalue(val1.getvalue + 10); val2.value := val2.value + 10; 10

이제이러한모든정의를사용하여다음과같이제네릭클래스를사용할수있습니다. procedure TFormIntfConstraint.btnValueClick(Sender: TObject); iclass: TInftClass<TGetValue>; iclass := TInftClass<TGetValue>.Create; iclass.set1 (TGetValue.Create (5)); iclass.set2 (TGetValue.Create (25)); Log ('Average: ' + IntToStr (iclass.getaverage)); iclass.increasebyten; Log ('Min: ' + IntToStr (iclass.getmin)); 이제네릭클래스의유연성을보여주기위해저는인터페이스에대해완전히다른구현을생성했습니다. TButtonValue = class(tbutton, IGetValue) public function GetValue: Integer; procedure SetValue (Value: Integer); class function MakeTButtonValue (Owner: TComponent; Parent: TWinControl): TButtonValue; { TButtonValue } function TButtonValue.GetValue: Integer; Result := Left; procedure TButtonValue.SetValue(Value: Integer); Left := Value; 클래스함수는임의위치의부모컨트롤내에버튼을생성하여다음과같은샘플코드에서사용됩니다. procedure TFormIntfConstraint.btnValueButtonClick(Sender: TObject); iclass: TInftClass<TButtonValue>; iclass := TInftClass<TButtonValue>.Create; iclass.set1 (TButtonValue.MakeTButtonValue (self, ScrollBox1)); iclass.set2 (TButtonValue.MakeTButtonValue (self, ScrollBox1)); Log ('Average: ' + IntToStr (iclass.getaverage)); Log ('Min: ' + IntToStr (iclass.getmin)); iclass.increasebyten; Log ('New Average: ' + IntToStr (iclass.getaverage)); 11

인터페이스참조와제네릭인터페이스제약조건비교 마지막예에서저는지정된인터페이스를구현하는개체와함께동작하는제네릭클래스를정의했습니다. 인터페이스참조에기반한표준 ( 비제네릭 ) 클래스를생성한다면유사한효과를거둘수있습니다. 사실상다음과같은클래스를정의할수있습니다. TPlainInftClass = class private val1, val2: IGetValue; public procedure Set1 (val: IGetValue); procedure Set2 (val: IGetValue); function GetMin: Integer; function GetAverage: Integer; procedure IncreaseByTen; 이두접근방법간의차이는무엇일까요? 차이점은위와같은클래스에서다른타입의두개체클래스가모두지정된인터페이스를구현하는경우해당두개체를 setter 메소드에전달할수있다는것입니다. 반면제네릭버전에서는지정된타입의개체만제네릭클래스의지정된인스턴스에전달할수있습니다. 따라서제네릭버전은타입확인측면에서더보수적이고엄격합니다. 중요한차이점은인터페이스기반버전을사용하는것은 Delphi 참조카운트메커니즘을사용하는것을의미하지만제네릭버전을사용하게되면클래스가지정된타입의일반개체를처리하며참조카운트가되지않는다는것입니다. 뿐만아니라제네릭버전은생성자제약조건과같은여러개의제약조건을가질수있으며개발자는제네릭버전을통해제네릭타입의실제타입을요청하는것과같은다양한제네릭함수를사용할수있습니다. 이는인터페이스를사용하는경우에는수행할수없습니다. ( 인터페이스로작업시사실상기본 TObject 메소드에액세스할수없습니다 ). 다시말해인터페이스제약조건을포함한제네릭클래스를사용하면인터페이스의단점없이이점을활용할수있습니다. 대부분의경우두가지접근방법이유사하지만어떤경우에는인터페이스기반솔루션이더유연하다는점에주목하십시오. 미리정의된제네릭컨테이너사용 C++ 언어의초기템플릿이배포된이후제네릭클래스가가장확실하게사용되어온방법중하나는제네릭컨테이너, 목록또는컨테이너에대한정의였습니다. Delphi 의자체 TObjectList 와같은개체목록을정의하면사실상어떤종류의객체라도잠재적으로보유할수있는목록이표시됩니다. 상속또는컴퍼지션을사용하면특정타입에대한사용자정의컨테이너를정의할수있지만이방법은진부할뿐만아니라에러를자주일으킬수있는접근방법입니다. Delphi 2009 는새 Generics.Collections 단위에서볼수있는제네릭컨테이너클래스의작은세트를정의합니다. 4 개의핵심컨테이너클래스는모두독립적인방법 ( 다른클래스에서상속받지않음 ) 으로구현됩니다. 모두동적배열을사용하여비슷한방법으로구현되며컨테이너단위의해당비제네릭컨테이너클래스에매핑됩니다. 12

TList<T> = class TQueue<T> = class TStack<T> = class TDictionary<TKey,TValue> = class 클래스이름을고려해보면이러한클래스간의논리적차이는명백합니다. 이러한클래스를테스트하는좋은방법은비제네릭컨테이너클래스를사용하는기존코드에서얼마나많은변경을수행해야하는지알아보는것입니다. 그예로저는 Mastering Delphi 2005 라는책의실제샘플프로그램을사용하여제네릭을사용하도록변환했습니다. TLIST<T> 사용 샘플프로그램에는 TDate 클래스를정의하는단위가있으며주형식은날짜의 TList 를참조하는데사용됩니다. 먼저 Generics.Collections 를참조하는사용절을추가한다음주형식필드의선언을다음과같이변경했습니다. private ListDate: TList <TDate>; 물론목록을생성하는주형식 OnCreate 이벤트처리기도업데이트해야하므로다음과같은구문을작성해야합니다. procedure TForm1.FormCreate(Sender: TObject); ListDate := TList<TDate>.Create; 이제나머지코드를있는그대로컴파일해볼수있습니다. 프로그램에는 TButton 개체를목록에추가하도록시도하는 의도한 버그가있습니다. 컴파일하는데사용되는해당코드는이제다음과같이실패합니다. procedure TForm1.ButtonWrongClick(Sender: TObject); // add a button to the list ListDate.Add (Sender); // Error: // E2010 Incompatible s: 'TDate' and 'TObject' 날짜의새목록은타입확인측면에서원래의제네릭목록포인터보다더강력합니다. 해당줄을제거하고프로그램에서컴파일및작동합니다. 여전히프로그램을개선할수있습니다. 다음은 ListBox 컨트롤에서목록의모든날짜를표시하는데사용되는원본코드입니다. I: Integer; ListBox1.Clear; for I := 0 to ListDate.Count - 1 do Listbox1.Items.Add((TObject(ListDate [I]) as TDate).Text); 프로그램이개체목록 (TObjectList) 이아닌포인터목록 (TList) 을사용하고있기때문에캐스트가매끄럽지못합니다. 원본데모날짜가 TObjectList 클래스날짜보다앞서기때문일수있습니다! 다음을작성하면프로그램을쉽게개선할수있습니다. 13

for I := 0 to ListDate.Count - 1 do Listbox1.Items.Add(ListDate [I].Text); 이코드에대한또다른개선방법은일반 for loop 대신열거 ( 미리정의된제네릭목록이완벽히지원 ) 를사용하는것입니다. adate: TDate; for adate in ListDate do Listbox1.Items.Add(aDate.Text); 마지막으로 TDate 개체를가진제네릭 TObjectList 를사용하여프로그램을개선할수있지만이것에대해서는다음섹션에서설명하겠습니다. 이미설명했듯이 TList<T> 제네릭클래스는높은수준의호환성을제공합니다. Add, Insert, Remove 및 IndexOf 와같은모든클래식메소드가있습니다. Capacity 및 Count 속성도있습니다. 이상하게도 Items 가 Item 이되지만기본속성이되면거의참조를하지않게됩니다. TLIST<T> 정렬 정렬이작동하는방식은아주흥미롭습니다. ( 여기에서의목표는정렬지원을앞의예에추가하는것입니다.) Sort 메소드는다음과같이정의됩니다. procedure Sort; overload; procedure Sort(const AComparer: IComparer<T>); overload; IComparer<T> 는 Generic. Defaults 단위내에선언됩니다. 첫번째버전의프로그램을호출하면프로그램은 TList<T> 의기본생성자로초기화된기본비교자를사용합니다. 이경우에서는쓸모가없습니다. 대신에 IComparer<T> 인터페이스의적합한구현을정의해야합니다. 타입호환성을위해특정 TDate 클래스에서작동하는구현을정의해야합니다. 다음섹션에서설명할익명메소드를포함하여이를수행할수있는방법은여러가지가있습니다. 이흥미로운기술은몇가지의제네릭사용패턴을표시하고 TComparer라고불리는 Generics.Defaults 단위의일부인구조클래스를활용할수있는기회를제공합니다. 클래스는다음과같이인터페이스의추상및제네릭구현으로정의됩니다. TComparer<T> = class(tinterfacedobject, IComparer<T>) public class function Default: IComparer<T>; class function Construct( const Comparison: TComparison<T>): IComparer<T>; function Compare(const Left, Right: T): Integer; virtual; abstract; 여기서해야하는작업은특정데이터타입에대한제네릭클래스 ( 예의경우 TData) 를인스턴트화하고특정타입에대한 Compare 메소드를구현하는구체적인클래스를상속하는것입니다. 잠시면배울수있는코딩관용구를사용하여다음과같이두개의작업을한번에 14

수행할수있습니다. TDateComparer = class(tcomparer<tdate>) function Compare(const Left, Right: TDate): Integer; override; 이코드를보면많은사람들이이상하게생각할것입니다. 새클래스가제네릭클래스의특정인스턴스에서상속되면다음과같이두개의개별단계로표현할수있습니다. TAnyDateComparer = TComparer<TDate>; TMyDateComparer = class(tanydatecomparer) function Compare(const Left, Right: TDate): Integer; override; 여기에서강조하려는핵심사항은아니지만소스코드에서 Compare 함수의실제구현을볼수있습니다. 그렇지만목록을정렬하더라도 IndexOf 메소드는 TStringList 클래스와달리목록을활용하지는않습니다. 익명메소드를사용한정렬 이전섹션에나온정렬코드는꽤복잡해보이며실제로도복잡합니다. 정렬함수를 Sort 메소드로직접전달하는것이훨씬쉬우면서도깨끗합니다. 과거에는일반적으로함수포인터를전달하여정렬을수행했습니다. Delphi 2009 에서는익명메소드를전달하여이를수행할수있습니다. 사실상 TList<T> 클래스에있는 Sort 메소드의 IComparer<T> 매개변수는다음과같이정의된익명메소드를매개변수로전달하는 TComparer<T> 의 Construct 메소드를호출하여사용할수있습니다. TComparison<T> = reference to function(const Left, Right: T): Integer; 실제로타입 - 호환함수를작성하고다음과같이해당함수를매개변수로전달할수있습니다. function DoCompare(const Left, Right: TDate): Integer; ldate, rdate: TDateTime; ldate := EncodeDate(Left.Year, Left.Month, Left.Day); rdate := EncodeDate(Right.Year, Right.Month, Right.Day); if ldate = rdate then Result := 0 else if ldate < rdate then Result := -1 else Result := 1; procedure TForm1.ButtonAnonSortClick(Sender: TObject); ListDate.Sort (TComparer<TDate>.Construct (DoCompare)); 이방법이너무일반적인것으로생각되는경우다음과같이개별함수의선언을피하고개별 15

함수 ( 해당소스코드 ) 를매개변수로서 Construct 메소드에보내는것을고려해볼수있습니다. procedure TForm1.ButtonAnonSortClick(Sender: TObject); ListDate.Sort(TComparer<TDate>.Construct( function (const Left, Right: TDate): Integer ldate, rdate: TDateTime; ldate := EncodeDate(Left.Year, Left.Month, Left.Day); rdate := EncodeDate(Right.Year, Right.Month, Right.Day); if ldate = rdate then Result := 0 else if ldate < rdate then Result := -1 else Result := 1; end)); 이예는익명메소드를보여주는간단한예로서자세한내용은나중에학습하게될것입니다. 이번최종버전은이전섹션에서다룬원본보다훨씬쉽게작성할수있습니다. 그렇지만파생클래스를포함하는것이대부분의 Delphi 개발자에게보다깨끗하게보이고이해하기쉬울수있습니다. 익명메소드 ( 클로저 ) Delphi 언어에서는프로시저타입 ( 포인터를프로시저및함수에선언하는타입 ) 과메소드포인터 ( 포인터를메소드에선언하는타입 ) 를오랫동안사용해왔습니다. 프로시저타입과포인터를직접적으로자주사용하지는않더라도이는모든개발자들이작업에사용하는 Delphi 의주요기능입니다. 사실메소드포인터타입은 VCL 의이벤트처리기에대한기초가됩니다. 이벤트처리기를선언할때마다, 그것이순수 Button1Click 이라하더라도개발자는메소드포인터를사용하는이벤트 ( 이경우 OnClick 이벤트 ) 에연결되는메소드를선언하게됩니다. 익명메소드는다른위치에서정의한메소드의이름이아니라메소드의실제코드를매개변수로전달함으로써이기능을확장합니다. 그렇지만이것이유일한차이점은아닙니다. 익명메소드가다른기술과매우다른부분은로컬변수의수명을관리하는방법입니다. 익명메소드는 Delphi 에서는새기능이지만수년간다른프로그래밍언어 ( 특히동적언어 ) 에서다른형식으로또한다른이름으로사용되어져왔습니다. 제경우에는 JavaScript 에서의마감, 특히 jquery (www.jquery.org) 라이브러리및 AJAX 호출작업을많이해보았습니다. C# 에서의해당기능은익명제어입니다. 여기서는마감과다양한프로그래밍언어에서의관련기술을비교하지않고대신 Delphi 2009 에서마감이어떻게작동되는지에대한정보를기술하도록하겠습니다. 16

익명메소드의구문및의미 Delphi 의익명메소드는표현식컨텍스트에서메소드값을생성하는메커니즘입니다. 다소복잡한정의이지만메소드포인터와의핵심적인차이를나타내주는것은표현식컨텍스트라는말입니다. 익명메소드를설명하기전에매우간단한코드예부터시작하도록하겠습니다. 다음은익명메소드타입선언으로, 이를통해 Delphi 가강력한타입의언어로계속사용될수있게됩니다. TIntProc = reference to procedure(n: Integer); 선언에사용되는키워드에서만참조메소드와차이를보입니다. TIntMethod = procedure(n: Integer) of object; 익명메소드변수 익명메소드타입이있으면다음과같이이타입의변수를선언하고타입 - 호환익명메소드를할당하고변수를통해해당메소드를호출할수있습니다. procedure TFormAnonymFirst.btnSimpleVarClick(Sender: TObject); anintproc: TIntProc; anintproc := procedure(n: Integer) Memo1.Lines.Add(IntToStr(n)); anintproc (22); 현재위치코드를포함한실제프로시저를변수에할당하는데사용되는구문을눈여겨보십시오. 이구문은과거의 Pascal 에서볼수없었던구문입니다. 익명메소드매개변수 보다놀라운구문을포함하는좀더흥미로운예를들자면, 익명메소드를매개변수로서함수에전달할수있다는것입니다. 다음과같이익명메소드매개변수를사용하는함수가있다고가정해보겠습니다. procedure CallTwice (value: Integer; anintproc: TIntProc); anintproc (value); Inc(value); anintproc(value); 함수는두개의연속정수값으로두번에걸쳐매개변수로서전달된메소드를호출합니다. 한 17

번은매개변수로서전달되며다른한번은그뒤에수반됩니다. 실제익명메소드를함수에전달하여다음과같이직접적인현재위치코드를포함한함수를호출합니다. procedure TFormAnonymFirst.btnProcParamClick(Sender: TObject); CallTwice(48, procedure(n: Integer) Memo1.Lines.Add(IntToHex(n, 4)); end); CallTwice (100, procedure(n: Integer) Memo1.Lines.Add(FloatToStr(Sqrt(n))); end); 구문의측면에서프로시저가괄호와함께매개변수로서전달되고세미콜론 (;) 으로종료되지않는것을눈여겨보십시오. 코드의실제결과는 48 및 49 를지정하여 IntToHex 를, 100 및 101 제곱근으로 FloatToStr 을호출한값이며다음과같이출력됩니다. 0030 0031 10 10.0498756211209 로컬변수사용 사용하는구문이 그다지훌륭하지 않다하더라도메소드포인터를사용하면동일한효과를얻을수있습니다. 익명메소드를명확히차별시켜주는것은익명메소드가호출메소드의로컬변수를참조할수있는방법입니다. 다음코드를고려해보십시오. procedure TFormAnonymFirst.btnLocalValClick(Sender: TObject); anumber: Integer; anumber := 0; CallTwice (10, procedure(n: Integer) Inc (anumber, n); end); Memo1.Lines.Add(IntToStr(aNumber)); 여기에서여전히 CallTwice 프로시저에전달되는메소드는로컬매개변수 n 뿐아니라호출컨텍스트의로컬변수인 anumber 도사용합니다. 효과는무엇일까요? 익명메소드를두번호출하면매개변수가로컬변수에추가되어 ( 첫번째에는 10, 두번째에는 11) 해당로컬변수가수정됩니다. anumber 의최종값은 21 입니다. 로컬변수의수명연장 앞의예는흥미로운결과를보여주지만중첩함수호출의시퀀스와로컬변수를사용할수있다는 18

사실은놀랍지않습니다. 그러나익명메소드의장점은로컬변수를사용하여필요에따라수명을연장할수있다는사실에있습니다. 장황한설명보다는예를통해그것을설명하겠습니다. 저는클래스완성을사용하여다음과같이 TFormAnonymFirst 형식클래스에익명메소드포인터타입의속성을추가했습니다. ( 사실프로젝트의모든코드에사용한것과동일한익명메소드입니다.) private FAnonMeth: TIntProc; procedure SetAnonMeth(const Value: TIntProc); public property AnonMeth: TIntProc read FAnonMeth write SetAnonMeth; 그다음두개의추가버튼을형식에추가했습니다. 첫번째버튼은다음과같이로컬변수를사용하는익명메소드를속성에저장 ( 이전 btnlocalvalclick 메소드에서의방식과유사 ) 합니다. procedure TFormAnonymFirst.btnStoreClick(Sender: TObject); anumber: Integer; anumber := 3; AnonMeth := procedure(n: Integer) Inc (anumber, n); Memo1.Lines.Add(IntToStr(aNumber)); 이메소드를실행하면익명메소드는실행되지않고저장만됩니다. 로컬변수인 anumber 는 0( 영 ) 으로초기화되어수정되지않고메소드가종료될때로컬범위를벗어나위치가변경됩니다. 최소한이것은표준 Delphi 코드에서예상되는작업입니다. 이단계를위해양식에추가한두번째버튼은익명메소드라고하며, AnonMeth 속성에저장됩니다. procedure TFormAnonymFirst.btnCallClick(Sender: TObject); if Assigned(AnonMeth) then CallTwice(2, AnonMeth); 이코드를실행하면코드는스택에더이상존재하지않는메소드의로컬변수 anumber 를사용하는익명메소드를호출합니다. 그러나익명메소드는실행컨텍스트를캡처하기때문에변수는그대로있고익명메소드의해당지정된인스턴스 ( 메소드에대한참조 ) 가있는한사용될수있습니다. 더자세히알아보려면다음을수행하십시오. 저장버튼을한번누르고호출버튼을두번누르면사용중인것과동일한캡처된변수가다음과같이표시됩니다. 5 8 10 19

13 이제저장버튼을한번더누른다음다시호출을누릅니다. 로컬변수의값이재설정되는이유는무엇일까요? 새익명메소드인스턴스를할당하면자체실행컨텍스트와함께이전익명메소드인스턴스가삭제되고로컬변수의새인스턴스를포함한새실행컨텍스트가캡처됩니다. 전체시퀀스저장 - 호출 - 호출 - 저장 - 호출을실행하면다음과같은결과가생성됩니다. 5 8 10 13 5 8 다른일부언어에서수행하는동작과비슷한이동작은익명메소드가과거에문자그대로불가능했던기능을실행하는데사용할수있는매우강력한언어기능을가질수있다는것을보여줍니다. 기타새로운언어기능 Object Pascal 언어의많은새중요기능을살펴보다보면일부사소한기능을놓치기쉽습니다. 주석처리된 DEPRECATED 지시어 deprecated 지시어 ( 기호를표시하는데사용됨 ) 은호환성이문제가되는경우계속사용할수있지만이제컴파일러경고의일부로표시되는문자열이뒤에나올수있습니다. 다음과같은코드조각에서처럼프로시저를정의하고호출하는경우 procedure DoNothing; deprecated 'use DoSomething instead'; procedure TFormMinorLang.btnDepracatedClick(Sender: TObject); DoNothing; btndepracatedclick 메소드의호출위치에다음과같은경고가표시됩니다. W1000 Symbol 'DoNothing' is deprecated: 'use DoSomething instead' 이방법은사용하지않는기호의선언에주석을추가하는이전방법보다훨씬낫습니다. 이방법에서는에러메시지에서클릭하여기호가사용되는소스코드줄을열고선언위치로이동하여주석을찾습니다. 말할필요도없이위의코드는 Delphi 2007 에서컴파일되지않으며다음과같은에러가발생합니다. E2029 Declaration expected but string constant found 새 deprecated 기능은 Delphi 2009 RTL 및 VCL 에서는많이사용되지만이전버전의컴파일러와호환되지않기때문에타사공급업체는이기능을사용하는데제약이있을것입니다. 20

EXIT 에서값리턴 일반적으로 Pascal 함수는다음과같이함수이름을사용하여결과를할당하는데사용됩니다. function ComputeValue: Integer;... ComputeValue := 10; Delphi 는 Result 식별자를사용하여반환값을함수에할당하는대체코딩을제공해왔습니다. function ComputeValue: Integer;... Result := 10; 두개의접근방법은동일하며코드의플로우를변경하지않습니다. 함수결과를할당하고두개의개별문을사용할수있는현재실행을중지하려면, 결과를할당한다음 Exit 를호출하십시오. 문자열목록에있는지정된번호를포함하는문자열을검색하는다음코드조각은이접근방법에대한일반적인예입니다. function FindExit (sl: TStringList; n: Integer): string; I: Integer; for I := 0 to sl.count do if Pos(IntToStr (n), sl[i]) > 0 then Result := sl[i]; Exit; Delphi 2009 에서는두개의문을 Exit 에대한새특정호출로대체하여, C 언어반환문과비슷한방법으로함수의반환값을전달할수있습니다. 또한단일문을사용하여 /end 를지정하지않아도되므로더간결한버전으로위의코드를작성할수있습니다. function FindExitValue (sl: TStringList; n: Integer): string; I: Integer; for I := 0 to sl.count do if Pos(IntToStr (n), sl[i]) > 0 then Exit(sl[I]); 새별칭정수타입 엄격히말해컴파일러의변경사항이아니라시스템단위에추가된사항이긴합니다만, 이제서명된정수데이터타입및서명되지않은정수데이터타입에대해기억하기쉬운별칭세트를사용할수있습니다. 다음은컴파일러의미리정의된서명된정의타입및서명되지않은정의타입입니다. 21

ShortInt SmallInt Integer NativeInt Int64 Byte Word Cardinal NativeUInt UInt64 이러한타입은 Delphi 2007 및이전버전에이미존재하지만 64 비트타입은일부버전의컴파일러에만존재합니다. 컴파일러버전 (32 비트및향후 64 비트 ) 에따라달라지는 NativeInt 및 NativeUInt 타입은 Delphi 2007 에이미있지만문서화되지않았습니다. CPU 네이티브정수크기와일치하는데이터타입이필요한경우이러한타입을사용할수있습니다. 사실상정수타입은 32 비트에서 64 비트로이동시변경되지않도록되어있습니다. 시스템단위에의해추가된다음미리정의된별칭세트는 Delphi 2009 의새로운기능입니다. Int8 = ShortInt; Int16 = SmallInt; Int32 = Integer; UInt8 = Byte; UInt16 = Word; UInt32 = Cardinal; 새로운세트를추가하지않았더라도일반적으로 ShortInt 가 SmallInt 보다작은지기억하기가어렵고 Int16 또는 Int8 의실제구현을기억하기는쉽기때문에이미리정의된별칭세트가보다사용하기쉬울것입니다. 결론 Delphi 언어에추가된몇가지흥미로운기능을다루긴했지만컴파일러의이번버전에서가장큰차이점은제네릭에대한지원, 익명메소드에대한지원및제네릭과익명메소드의조합입니다. 이러한기능은 Delphi 언어를단순히확장하는것이아니라일반적인개체지향프로그래밍과 Delphi 에서전통적으로사용되어온이벤트중심프로그래밍접근방법이외의새프로그래밍패러다임에대한가능성을열었습니다. 클래스를한개이상의데이터타입에서매개변수화할수있는기능과루틴을매개변수로전달하는기능은새로운코딩스타일과 Delphi 응용프로그램의새로운설계방법을제시합니다. Delphi 2009 의언어기능은바로여기에있지만라이브러리와구성요소가이러한기능을완전히활용할때까지는시간이걸릴것입니다. Delphi 2009 를사용하면오늘바로새코딩기술을사용하여작업을시작할수있습니다. 필자에대하여 이문서는베스트셀러시리즈인 Mastering Delphi 의저작자 Marco Cantù 가 Embarcadero Technologies 를위해작성하였습니다. 이문서의내용은그의최근저서인 Delphi 2009 핸드북 " (http://www.marcocantu.com/dh2009) 에서발췌한것입니다. Marco Cantù 에대한정보는그의개인블로그 (http://blog.marcocantu.com) 에서읽을수있으며전자 22

메일 (marco.cantu@gmail.com) 을통해연락할수있습니다. Embarcadero Technologies Inc. 는애플리케이션개발자및데이터베이스전문가가자신이선택한환경에서소프트웨어애플리케이션을설계, 빌드및실행하는도구를사용할수있도록합니다. 전세계 3 백만이상의커뮤니티와 Fortune 지선정 100 대기업중 90 개기업이 Embarcadero 의 CodeGear 및 DatabaseGear 제품군을기반으로하여생산성을향상시키고개방적인협업및자유로운혁신을추구하고있습니다. Embarcadero 는 1993 년에설립되어캘리포니아샌프란시스코에본사가있으며전세계에사무소를두고있습니다. Embarcadero 의온라인주소는 www.embarcadero.com 입니다. Embarcadero 의주요제품인 DatabaseGear 의도구에는 ER/Studio, DBArtisan, Rapid SQL 및 Embarcadero Change Manager 가있습니다. 데브기어는미국 Embarcadero Technologies Inc. 와기존의코드기어한국지사의협력으로전략적으로설립된엠바카데로솔루션전문공급기업입니다. 데브기어는 Delphi, C++Builder, JBuilder, Delphi Prism 등개발툴제품들과 ER/Studio, PowerSQL, DB Artisan, EA/Studio 등의데이터베이스툴제품들에대한한국시장에공급은물론기술지원및교육을제공합니다. 데브기어웹사이트는 http://www.devgear.co.kr/ 이며제품에대한문의는 ask@embarcadero.kr 로하면됩니다. 23