2009-12-07 9 views
3

정확한 유형을 지정하지 않고 TDictionary를 반환하는 함수를 구현해야합니다.Delphi에서 제네릭을 사용하는 것이 안전합니까?

function GetMap: TDictionary; 

다음 반환 값 캐스트 :

type 
    TMyMapType: TDictionary<string,Integer>; 
var 
    MyMap: TMyMapType: 
begin 
... 
    MyMap := GetMap as TMyMapType; 
... 
end; 

편집 : 반환 값은,이 TDictionary<string,Integer>, TDictionary<string,string> 또는 TDictionary<string,Boolean>

난 결과 매개 변수로 TDictionary으로 함수를 선언 할 수있을 수 발견 내 세 가지 사전 형식과 호환 될 수있는 '일반'결과 매개 변수 형식을 선언 할 방법이없는 것으로 보입니다. 내가 오브젝트 파스칼 언어에없는

type 
     TMyMapType: TDictionary<string, ?>; 

(아직?) 수와 같은 뭔가가 필요 같은

는 것 같습니다.

static Map<String, Integer>getIntegerMap() { 
    Map<String, Integer> result = new TreeMap<String, Integer>() {}; 
    result.put("foo", Integer.valueOf(42)); 
    return result;   
} 

static Map<String, ?> getMap() { 
    return getIntegerMap(); 
} 

public static void main(String[] args) { 
    System.out.println(getMap().get("foo")); 
} 

답변

2

는 아니, "모든 TDictionary 버전에서 내려 기본 TDictionary 클래스"가 없습니다. 매개 변수 유형은 클래스 유형의 일부입니다. TDictionary<T, U>의 부모 클래스는 TEnumerable<TPair<T, U>>이고 그 부모 클래스는 TObject입니다.

이것은 다소 성가기는하지만 유형 안전성을 유지해야합니다. TDictionary<string, TMyObject>이 있고 TDictionary<string, TObject>을 기대하는 함수로 전달했다고 가정 해 보겠습니다. TObject 매개 변수에 TMyObject를 전달할 수 있기 때문에이 기능이 작동 할 것으로 예상 할 수 있습니다. 그러나 그렇지 않습니다. 좋은 이유가 있습니다.

컴파일러는 컴파일 타임에 수신 함수 내에서 실제 유형을 확인할 수 없으므로 사전을 가져 오지 않고 .Add(Self.Name, Self) (여기서 Self는 TForm 또는 기타 항목)을 호출하고 TMyObject는 호출하지 않습니다. . 모든 객체 참조는 크기가 sizeof (포인터)이기 때문에 잘 작동하는 것처럼 보일 수 있지만 두 번째 매개 변수가 무엇인지 알고있는 코드에서 다시 얻으면 큰 문제가 발생합니다.

수신 기능에 제약 조건을 넣어 유형 안전성을 손상시키지 않으면 서 Generics를 작동시킬 수있는 방법이 있지만 Delphi는 현재이 기능을 구현하지 않습니다. Delphi Prism은 다음 릴리스에서 Delphi 팀이 구현하도록 노력했지만, 우리는 다음 릴리스에서이를 구현해야합니다 ...

+0

이 응답을 읽은 후 고맙습니다. http://www.ibm.com/developerworks/java/library/j-jtp04298.html ('캡처 도우미'를 사용하여 가능한 해결책을 보여줍니다.) 문제점을 이해합니다.내 단순한 경우 반환 형식에만 필요하기 때문에 기본 래퍼 개체가있는 TDictionary 가 해결 방법이 될 수 있습니다. – mjn

0

의 GetMap를 호출, 당신은 이미 결과가 TDictionary 될 것이라는 점을 알고있다 : 자바에서는이 같은 것입니다. 왜 T와 U의 TDictionary를 리턴하는 T와 U의 Generic 함수 GetMap을 생성하지 않는가? 이처럼

:

function GetMap<T, U>: TDictionary<T, U>; 

은 그럼 당신은 캐스팅없이이 작업을 수행 할 수 있습니다 :

var 
    MyMap: TMyMapType; 
begin 
    MyMap := GetMap<string, integer>(); 
+0

function GetMap : TDictionary ; 컴파일되지 않습니다 - 함수 GetMap : TDictionary; 너무 컴파일되지 않습니다. 나는 튜토리얼 모드에서 다시 읽는다. :) – mjn

+1

'GetMap'이 멤버 메소드 인 경우 IMHO가 잘 작동해야합니다. – jpfollenius

관련 문제