简体   繁体   English

使用他的ClassType转换TObject?

[英]cast TObject using his ClassType?

how can i make my code to work ? 我怎样才能使我的代码工作? :) i`ve tried to formulate this question but after several failed attempts i think you guys will spot the problem faster looking at the code than reading my 'explanations'. :)我试图制定这个问题,但经过几次失败的尝试后,我认为你们会更快地发现问题,而不是阅读我的“解释”。 thank you. 谢谢。

setCtrlState([ memo1, edit1, button1], False);

_ _

procedure setCtrlState(objs: array of TObject; bState: boolean = True);
var
  obj: TObject;
  ct: TClass;
begin
  for obj in objs do
  begin
    ct := obj.ClassType;


    if (ct = TMemo) or (ct = TEdit) then
      ct( obj ).ReadOnly := not bState;        // error here :(

    if ct = TButton then
      ct( obj ).Enabled:= bState;        // and here :(

  end;
end;

You must explicitly cast object to some class. 您必须显式地将对象强制转换为某个类。 This should work: 这应该工作:

 procedure setCtrlState(objs: array of TObject; bState: boolean = True);
 var
   obj: TObject;
   ct: TClass;
 begin
  for obj in objs do
  begin
    ct := obj.ClassType;

    if ct = TMemo then
      TMemo(obj).ReadOnly := not bState
    else if ct = TEdit then
      TEdit(obj).ReadOnly := not bState
    else if ct = TButton then
      TButton(obj).Enabled := bState;
  end;
end;

This can be shortened using " is " operator - no need for ct variable: 这可以使用“ is ”运算符缩短 - 不需要ct变量:

 procedure setCtrlState(objs: array of TObject; bState: boolean = True);
 var
   obj: TObject;
 begin
   for obj in objs do
   begin
     if obj is TMemo then
       TMemo(obj).ReadOnly := not bState
     else if obj is TEdit then
       TEdit(obj).ReadOnly := not bState
     else if obj is TButton then
       TButton(obj).Enabled := bState;
   end;
 end;

It would be easier to use RTTI instead of explicit casting, ie: 使用RTTI而不是显式转换会更容易,即:

uses
  TypInfo;

setCtrlState([ memo1, edit1, button1], False);

procedure setCtrlState(objs: array of TObject; bState: boolean = True);
var
  obj: TObject;
  PropInfo: PPropInfo;
begin
  for obj in objs do
  begin
    PropInfo := GetPropInfo(obj, 'ReadOnly');
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, not bState);

    PropInfo := GetPropInfo(obj, 'Enabled');
    if PropInfo <> nil then SetOrdProp(obj, PropInfo, bState);
  end;
end;

You need to cast the ct object to a TMemo/TEdit/TButton before you can set properties on the object. 在设置对象的属性之前,需要将ct对象强制转换为TMemo / TEdit / TButton。

The line where you're getting errors are erroring because ct is still a TClass, not a TButton/etc. 你遇到错误的行是错误的,因为ct仍然是TClass,而不是TButton /等。 If you cast to a TButton, then you'll be able to set enabled to true. 如果你转换为TButton,那么你将能够将enabled设置为true。

I recommend reading up on casting in Delphi . 我建议阅读Delphi中的cast Personally, I would recommend using the as/is operators instead of using ClassType, as well. 就个人而言,我建议使用as / is运算符,而不是使用ClassType。 The code will be simpler in that case, and much more understandable. 在这种情况下,代码将更简单,更容易理解。


Personally, I would write this more like: 就个人而言,我会更喜欢这样写:

procedure setCtrlState(objs: array of TObject; bState: boolean = True);
var
  obj: TObject;
begin
  for obj in objs do
  begin
    // I believe these could be merged by using an ancestor of TMemo+TEdit (TControl?)
    // but I don't have a good delphi reference handy
    if (obj is TMemo) then
        TMemo(obj).ReadOnly := not bState;

    if (obj is TEdit) then
        TEdit(obj).ReadOnly := not bState;

    if (obj is TButton) then
        TButton(obj).Enabled := bState;
  end;
end;

There is no need to cast to TMemo and TEdit separately, as they are both descendants from common parent class, which have ReadOnly property: 没有必要单独转换为TMemo和TEdit,因为它们都是来自公共父类的后代,它具有ReadOnly属性:

procedure TForm1.FormCreate(Sender: TObject);

  procedure P(const Obj: TComponent);
  begin
    if Obj is TCustomEdit then
      TCustomEdit(Obj).ReadOnly := True;
  end;

begin
  P(Memo1);
  P(Edit1);
end;

You can avoid referencing various units and the explicit casting if you do not mind a small performance hit and limit the changes to published properties. 如果您不介意小的性能损失并限制对已发布属性的更改,则可以避免引用各种单位和显式转换。 Have a look at the TypInfo unit included with Delphi. 看看Delphi附带的TypInfo单元。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM