i want typecast using with class functions.
i have base (TBase),derived (TDer) and typecasting (TMyType) class.
Ver : Delphi 7
TBase = class;
TDer = class;
TMyType = class;
TBase = class
function Say : String;
class function MYType:TMyType;
end;
TDer = class(TBase)
a: string;
b: string;
function Say2 : String;
end;
TMyType=class(TBase)
class function AsDer:TDer;
end;
{ TBase }
class function TBase.MYType: TMyType;
begin
Result:=TMyType(Self);
end;
function TBase.Say: String;
begin
Result:='TBase';
end;
{ TDer }
function TDer.Say2: String;
begin
Result:='TDer';
end;
{ TMyType }
class function TMyType.AsDer: TDer;
begin
Assert(Assigned(Self));
Result := TDer(Self) ;
end;
Sample usage is below, it’s calls method but when set/get field’s raise error.
procedure TForm1.Button1Click(Sender: TObject);
var
b,c:TBase;
begin
b:=TDer.Create;
c:=b.MYType.AsDer;
ShowMessage(b.MYType.AsDer.Say2); // OK. Running
if (@b<>@c) then ShowMessage('Not Equal'); // Shows message, Why ?
b.MYType.AsDer.a:='hey'; // Error
FreeAndNil(b);
end;
Do you have any idea?
The fundamental problem is here:
This is a class method and so
Selfrefers to a class and not an instance. Casting it to be an instance does not make it so. Exactly the same error is made in yourAsDerclass function.Looking into the specifics, the call to
is benign and appears to work fine because it does not refer to
Self. You could equally writeTDer(nil).Say2and that code would also work without problem. Now, if the functionSay2referred toSelf, that is referred to an instance, then there would be a runtime error.always evaluates to true because you are comparing the locations of two distinct local variables.
is a runtime error because
AsDerdoes not return an instance ofTDer. So when you attempt to write toayou have a runtime error. This is because you are referring toSelfand that’s why this code fails, but the earlier call toSay2does not.I’m not really sure what you are trying to do here, but it looks all wrong. Even if you were working with instance methods rather than class methods, it would simply be wrong to case a base class instance to a derived class instance. If something is the wrong type, no amount of casting will turn it into the right type.
Furthermore, you should never write code that has a method of
TBaseassuming it is of typeTDerived. The base class should know absolutely nothing of its derived classes. That is one of the very basic tenets of OOP design.