문제

유형 이름이 포함 된 텍스트 문자열이 주어지면 적절한 유형 자체를 얻을 수있는 방법이 있습니까?

나는 다음과 같은 일을하고 싶다 :

type
  TSomeType<T> = class
    // yadda yadda
  end;

procedure DoSomething;
var
  obj : TObject;
begin
  o := TSomeType<GetTypeByName('integer')>.Create;
  // do stuff with obj
end;

나는 온라인에서 여러 RTTI 설명을보고 델파이 유닛을 살펴보고 내가 찾고있는 것을 보지 못했습니다. 이게 가능해?

도움이 되었습니까?

해결책

아니요, 제네릭은 전적으로 컴파일 타임입니다.

다른 팁

Delphi 2010의 새로운 RTTI 장치에는 장치의 인터페이스 섹션에서 선언 된 유형을 검색하는 방법이 있습니다. 주어진 유형에 대해 TRttiType 인스턴스, TRttiType.QualifiedName 속성은 사용할 수있는 이름을 반환합니다 TRttiContext.FindType 나중에 유형을 검색합니다. 자격을 갖춘 이름은 전체 단위 이름 (존재하는 경우 네임 스페이스 포함)이며, '.', 전체 유형 이름 (중첩 된 경우 외부 유형 포함)입니다.

따라서 정수 유형의 표현을 검색 할 수 있습니다 ( TRttiType) 와 함께 context.FindType('System.Integer').

그러나이 메커니즘은 컴파일 시간에 인스턴스화되지 않은 일반 유형의 인스턴스화를 검색하는 데 사용할 수 없습니다. 런타임의 인스턴스화에는 런타임 코드 생성이 필요합니다.

항상 유형을 일종의 레지스트리 (문자열 목록 또는 사전에 의해 관리)에 등록하고 공장 기능을 만들어 적절한 개체를 반환 할 수 있습니다. 불행히도 당신은 어떤 유형이 필요한지 미리 알아야 할 것입니다. Delphi 기능과 유사한 것은 RegisterClass 및 FindClass (클래스 단위). 내 생각은 일반 템플릿 유형을 목록에 직접 넣는 것입니다.

가능한 사용의 예 :

RegisterCustomType('Integer',TSomeType<Integer>);
RegisterCustomType('String',TSomeType<String>);

if FindCustomType('Integer') <> nil then
  O := FindCustomType('Integer').Create;

편집하다: 다음은 Generics의 tdictionary를 사용하는 특정 간단한 구현입니다. 레지스트리 스토리지를 처리하기위한 수집 ... 독자에게 간단한 연습으로 유용한 방법으로 이것을 추출합니다.

var
  o : TObject;
begin
  TypeDict := TDictionary<String,TClass>.Create;
  TypeDict.Add('integer',TList<integer>);
  if TypeDict.ContainsKey('integer') then
    o := TypeDict.Items['integer'].Create;
  if Assigned(o) then
    ShowMessage(o.ClassName);
end;

다른 편집 : 나는 어제 밤 에이 생각을 주었고이 개념에 합병 할 수있는 또 다른 기술을 발견했습니다. 인터페이스. 다음은 아무것도하지 않지만 쉽게 확장 할 수 있습니다.

TYPE
  ITest = interface
    ['{0DD03794-6713-47A0-BBE5-58F4719F494E}']
  end;

  TIntfList<t> = class(TList<T>,ITest)
  public
    function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  end;

procedure TForm1.Button7Click(Sender: TObject);
var
  o : TObject;
  fTestIntf : ITest;
begin
  TypeDict := TDictionary<String,TClass>.Create;
  TypeDict.Add('integer',TIntfList<integer>);
  if TypeDict.ContainsKey('integer') then
    o := TypeDict.Items['integer'].Create;
  if Assigned(o) and Supports(o,ITest,fTestIntf) then
    ShowMessage(o.ClassName);
end;

물론 QueryInterface, _addref 및 _Release 메소드를 구현하고 인터페이스를 확장하여 더 유용한 작업을 수행해야합니다.

제네릭과 기본 유형을 잊어 버리면 "레지스터 클래스"기능이 도움이됩니다. 그러나 제네릭이나 기본 유형에는 효과가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top