procedure TMainForm.FormCreate(Sender: TObject); begin // this action will be tied to the rectangle implementing // the "faded" background of the stand (see 'background_cancel') // element in StyleBook1 and also tied to Button_cancel TButton // on the frame
FrameStand1.CommonActions.Add('*_cancel', procedure(AInfo: TFrameInfo<TFrame>) begin if (AInfo.Frame is TColorDialogFrame) then TColorDialogFrame(AInfo.Frame).Cancel; end ); end; 这里提示错误: [dcc32 Error] uMain.pas(88): E2010 Incompatible types: 'System.SysUtils.TProc<uMain.TMyBase>' and 'Procedure'
要改成这样: FrameStand1.CommonActions.Add('*_cancel', procedure(AInfo: TSubjectInfo) begin if (AInfo is TFrameInfo<TFrame>) and (TFrameInfo<TFrame>(AInfo).Frame is TColorDialogFrame) then TColorDialogFrame(TFrameInfo<TFrame>(AInfo).Frame).Cancel; end );
然而,并非一切都是可取的。 ---------- As many of you may already know, Object Pascal is heavily based on the object's type, more precisely, on the "name" of the object's type!
In this way, when translating the information, there is a conflict between the types (the names of the types) of the objects being referenced in the code, and, the compiler must be trying to make an inference at this point, and, in the last case, it it may throw an error more likely when it is not known for sure in the identification of the same.
In this way, many error messages are not, in fact, the real message, but the most likely among many messages.
In this way, in addition to the programmer's mistake when using an inherited class (sub-class) in the place where an ancestor class is expected, it can also contribute to the confusion in the end.
Thus, as it is said in the game: Assassins Creed: Everything is allowed....
procedure TMyTestObj.SetSS(const Value: string); begin FSS := Value; end;
{ TMyAction<T> }
procedure TMyAction<T>.Add(a: string; AProc: TProc<T>); var MyInstanceX: T; begin if Assigned(AProc) then begin // MyInstanceX := T(TMyBase.Create); // to TMyBase usage... // MyInstanceX := T(TMyTestObj.Create); // to TMyTestObj usage... MyInstanceX := T.Create; // to "T" generic usage... try AProc(MyInstanceX); // if (TObject(MyInstanceX).InheritsFrom(TMyTestObj)) then ShowMessage(TMyTestObj(MyInstanceX).FSS); finally if Assigned(MyInstanceX) then MyInstanceX.Free; end; end; end;
{ TForm1 }
procedure TForm1.DoAction; var // L: TMyAction<TMyBase>; L: TMyAction<TMyTestObj>; begin L :=nil; // this works too! // // L := TMyAction<TMyBase>.Create; // uncomment this line // or... // L := TMyAction<TMyTestObj>.Create; // or uncomment this line // try // // 10.4.2下, 注释的语句编译错误: (10.3.3 是可以正确编译的!!! // [dcc32 Error] uMain.pas(88): // E2010 Incompatible types: 'System.SysUtils.TProc<uMain.TMyBase>' and 'Procedure'
L.Add('aaa', procedure(K: TMyTestObj) begin K.SS := 'ddd'; // <----- OK NOW for TMyTestObj end);
// 10.4.2 要这样处理: 用基类做参数就不会错.... L.Add('aaa', // procedure(K: TMyBase ) // or... procedure(K: TMyTestObj) begin if K.InheritsFrom(TMyTestObj) then ShowMessage('K.InheritsFrom(TMyTestObj) ') else if K.InheritsFrom(TMyBase) then ShowMessage('K.InheritsFrom(TMyBase) '); // if K is TMyTestObj then begin TMyTestObj(K).SS := 'now: ' + DateTimeToStr(now); end else ShowMessage(K.ClassName + ', K is NOT TMyTestObj ');
end); finally if Assigned(L) then L.Free; end; end;
initialization
ReportMemoryLeaksOnShutdown := true;
finalization
end.
此帖子包含附件: 大小:91.3K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
type TAAA = TMyAction<TMyBase>; TBBB = TMyAction<TMyTestObj>;
procedure TForm1.Button2Click(Sender: TObject); begin if TAAA = TBBB then; // [dcc32 Error] uView.MainForm.pas(101): E2010 Incompatible types: 'class of uView.MainForm.TMyAction<uView.MainForm.TMyBase>' and //.......... 'class of uView.MainForm.TMyAction<uView.MainForm.TMyTestObj>' end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3