我使用的是一个非常大的delphi第三方库,没有源代码,这个库有几个带抽象方法的类.我需要确定运行时Descendant类实现abtract方法的时间,以避免EAbstractError: Abstract Error向用户显示自定义消息或使用其他类代替.
例如,在此代码中,我想在运行时检查是否MyAbstractMethod已实现.
type
TMyBaseClass = class
public
procedure MyAbstractMethod; virtual; abstract;
end;
TDescendantBase = class(TMyBaseClass)
public
end;
TChild = class(TDescendantBase)
public
procedure MyAbstractMethod; override;
end;
TChild2 = class(TDescendantBase)
end;
Run Code Online (Sandbox Code Playgroud)
我如何确定在运行时的Descendant类中是否实现了抽象方法?
RRU*_*RUZ 10
你可以使用Rtti,GetDeclaredMethods函数获取在反射(当前)类型中声明的所有方法的列表.因此,您可以检查此函数返回的列表中是否存在该方法.
function MethodIsImplemented(const AClass:TClass;MethodName : string): Boolean;
var
m : TRttiMethod;
begin
Result := False;
for m in TRttiContext.Create.GetType(AClass.ClassInfo).GetDeclaredMethods do
begin
Result := CompareText(m.Name, MethodName)=0;
if Result then
break;
end;
end;
Run Code Online (Sandbox Code Playgroud)
或者您可以比较TRttiMethod的Parent.Name属性并检查是否与当前的类名匹配.
function MethodIsImplemented(const AClass:TClass;MethodName : string): Boolean;
var
m : TRttiMethod;
begin
Result := False;
m:=TRttiContext.Create.GetType(AClass.ClassInfo).GetMethod(MethodName);
if m<>nil then
Result:=CompareText(AClass.ClassName,m.Parent.Name)=0;
end;
Run Code Online (Sandbox Code Playgroud)
查看TStream.Seek()VCL 源代码(在 参考资料中Classes.pas)中该方法的 32 位版本的实现。Seek()它会在调用之前执行检查以确保 64 位版本已被覆盖。它不涉及TRttiContext查找来做到这一点,只是通过其父/子 VTable 条目进行简单循环,类似于 Zo\xc3\xab 的答案所示。
function ImplementsAbstractMethod(AObj: TMyBaseClass): Boolean;
type
TAbstractMethod = procedure of object;
var
BaseClass: TClass;
BaseImpl, Impl: TAbstractMethod;
begin
BaseClass := TMyBaseClass;
BaseImpl := TMyBaseClass(@BaseClass).MyAbstractMethod;
Impl := AObj.MyAbstractMethod;
Result := TMethod(Impl).Code <> TMethod(BaseImpl).Code;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2597 次 |
| 最近记录: |