首页 > 解决方案 > delphi 类在运行时确定

问题描述

Delphi XE+ 中有没有办法创建一个函数,其结果在运行时确定?

例如:

function ARuntimeClass(achoice: integer): ClassType;
begin
   case achoice of
     0: Result := TEdit;
     1: Result := TMemo;
     2: Result := TCheckbox;
     3: Result := TComboBox;
   end;
end;

然后,在运行时:

var
  aComponent: TComponent;       
begin
  aComponent := FindComponent('SomeComponent234');
  //then process
  ARuntimeClass(2).Checked := True;
  aComponent := FindComponent('SomeComponent123');
  //then process
  ARuntimeClass(0).Text := 'Chosen';    
end;

我正在尝试在运行时进行类型转换。

标签: delphitypes

解决方案


是的,您可以使用元类类型(表示所有类类型)、(表示从 派生的类) 、 (表示从 派生的所有类)等元类类型作为函数结果返回类类型。System.TClassClasses.TComponentClassTComponentTControlClassTControl

function ARuntimeClass(achoice: integer): TControlClass;
begin
  case achoice of
    0: Result := TEdit;
    1: Result := TMemo;
    2: Result := TCheckbox;
    3: Result := TComboBox;
  end;
end;

虽然,您可以简单地使用aComponent.ClassType()来访问对象的真实元类类型,但您不需要单独的函数。

但是,仅仅访问元类类型并不能真正解决您的问题。您不能使用元类对对象指针进行类型转换以访问任何特定于类型的成员。对于您正在尝试的内容,您需要改用 RTTI,例如:

使用旧式 RTTI(D2010 之前):

uses
  ..., TypInfo;

var
  aComponent: TComponent;       
  aProp: PPropInfo;
begin
  aComponent := FindComponent('SomeComponent234');
  //then process
  pProp := GetPropInfo(aComponent, 'Checked');
  if aProp <> nil then SetOrdProp(aComponent, aProp, True);

  aComponent := FindComponent('SomeComponent123');
  //then process
  aProp := GetPropInfo(aComponent, 'Text');
  if aProp = nil then aProp := GetPropInfo(aComponent, 'Caption');
  if aProp <> nil then SetStrProp(aComponent, aProp, 'Chosen');
end;

使用新型增强型 RTTI (D2010+):

uses
  ..., System.Rtti;

var
  aComponent: TComponent;       
  ctx: TRttiContext;
  rType: TRttiType;
  rProp: TRttiProperty;
begin
  aComponent := FindComponent('SomeComponent234');
  //then process
  rType := ctx.GetType(aComponent.ClassType);
  rProp := rType.GetProperty('Checked');
  if rProp <> nil then rProp.SetValue(aComponent, True);

  aComponent := FindComponent('SomeComponent123');
  //then process
  rType := ctx.GetType(aComponent.ClassType);
  rProp := rType.GetProperty('Text');
  if rProp = nil then rProp := rType.GetProperty('Caption');
  if rProp <> nil then rProp.SetValue(aComponent, 'Chosen');
end;

推荐阅读