Delphi 使用他的类类型强制转换为Object?

Delphi 使用他的类类型强制转换为Object?,delphi,tobject,Delphi,Tobject,如何使代码正常工作?:)我曾试图解释这个问题,但经过几次失败的尝试后,我想你们会比阅读我的“解释”更快地发现问题。多谢各位 setCtrlState([ memo1, edit1, button1], False); _ 在设置对象的属性之前,需要将ct对象强制转换为TMemo/TEdit/TButton 出现错误的行是错误的,因为ct仍然是TClass,而不是TButton/等。如果您强制转换为TButton,则可以将enabled设置为true 我建议你多读点书。就个人而言,我建议使用as

如何使代码正常工作?:)我曾试图解释这个问题,但经过几次失败的尝试后,我想你们会比阅读我的“解释”更快地发现问题。多谢各位

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


在设置对象的属性之前,需要将ct对象强制转换为TMemo/TEdit/TButton

出现错误的行是错误的,因为ct仍然是TClass,而不是TButton/等。如果您强制转换为TButton,则可以将enabled设置为true

我建议你多读点书。就个人而言,我建议使用as/is操作符,而不是使用ClassType。在这种情况下,代码会更简单,也更容易理解


就我个人而言,我更喜欢这样写:

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;

必须将对象显式强制转换为某个类。 这应该起作用:

 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;
这可以使用“
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;

无需分别强制转换到TMemo和TEdit,因为它们都是公共父类的后代,具有只读属性:

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;

如果不介意性能受到小的影响并限制对已发布属性的更改,则可以避免引用各种单元和显式强制转换。查看Delphi附带的TypInfo单元。

使用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;
使用
TypInfo;
setCtrlState([memo1,edit1,button1],False);
过程setCtrlState(objs:TObject数组;bState:boolean=True);
变量
对象:对象;
PropInfo:PPropInfo;
开始
对于objs中的obj,请执行以下操作
开始
PropInfo:=GetPropInfo(对象为“只读”);
如果PropInfo为nil,则SetOrdProp(obj,PropInfo,非bState);
PropInfo:=GetPropInfo(obj,‘Enabled’);
如果PropInfo为零,则SetOrdProp(obj、PropInfo、bState);
结束;
结束;

在每种情况下,第二次类型转换不应该是“TEdit”而不是“TMemo”?+0.5表示您必须对每种类型执行类型转换+0.5使用“是”我修正了Argalatyr提到的打字错误,我想你在每个块中都有一个额外的“结束”,更好的缩进会使这更明显。@Ian:我想你错过了第二个。这正是我想要的。非常感谢。
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;