在所有情况下我都记得,以下说明给出了相同的结果:
type
TMyClass = class(TObject);
TMyChildClass = class(TMyClass);
var
MyObj : TMyChildClass;
procedure TForm1.Test();
var
ResultA : Boolean;
ResultB : Boolean;
begin
//Using TObject.InheritsFrom
ResultA := MyObj.InheritsFrom(TMyClass);
//Using 'is' operator
ResultB := MyObj is TMyClass;
//Showing results
ShowMessage(
'InheritsFrom = ' + BoolToStr(ResultA, True) + sLineBreak +
'is = ' + BoolToStr(ResultB, True)
);
end;
使用is
运算符代替TObject.InheritsFrom
函数有什么不同吗?
答案 0 :(得分:9)
是的,有区别。 InheritsFrom
是类函数,它的主要目的是测试类IS
(从某个类继承)。
您不能在课程上使用is
运算符。
TMyChildClass is TMyClass
无法编译,但您可以使用TMyChildClass.InheritsFrom(TMyClass)
代替。
答案 1 :(得分:6)
is
运算符构建于InheritsFrom
之上。所以,
obj is TSomeClass
实现为
(obj <> nil) and obj.InheritsFrom(TSomeClass)
表达式obj.InheritsFrom(TSomeClass)
可能有点令人困惑,因为看起来InheritsFrom
是一个实例方法。实际上InheritsFrom
是一个类方法,obj
的运行时类作为InheritsFrom
指针传递给Self
。
基本上is
和InheritsFrom
执行相同的任务,至少在限制注意类时。请注意,is
更通用,也可以与接口一起使用,例如。
有明显的语法差异。即is
需要一个实例,而InheritsFrom
是一个类函数。虽然,正如我们所看到的,Delphi语言确实支持在实例引用上调用类函数。另一个明显的区别是is
有一个nil
引用的内置测试。
这些只是语法上的差异,但基本操作是相同的,is
调用InheritsFrom
这一事实证明了这一点。
答案 2 :(得分:1)
我想提到至少一种情况
obj is TSomeClass
运算符的行为不完全与
(obj <> nil) and obj.InheritsFrom(TSomeClass)
当编译器“认为” obj只能是TSomeClass成员时,它将跳过TObject.InheritsFrom()调用(使用 is 运算符时),并且仅测试nil指针。可以通过以下测试代码(在10.2.3 Tokyo和10.3.3 Rio中进行测试)确认这一点:
procedure TestForTStringList(obj: TStringList);
begin
if obj.InheritsFrom(TStringList) then
begin
//
end;
if obj is TStringList then
begin
//
end;
end;
此代码产生以下汇编代码
在此方法中,我们可以看到obj.InheritsFrom()实际上调用了TObject.InheritsFrom()方法。另一方面,与 is 运算符相关的代码仅检查nil指针。
在无法在编译时确定类的情况下,与编译器为 is 运算符生成的代码进行比较:
上面,该变量被声明为TObject,因此编译器实际上调用了System.IsClass(),即:
function _IsClass(const Child: TObject; Parent: TClass): Boolean;
begin
Result := (Child <> nil) and Child.InheritsFrom(Parent);
end;
您可能会认为这没有什么区别,但是在某些特定的调试方案中却没有关系:使用FastMM时,将选中检查释放对象上的方法调用的选项。在这种情况下,FastMM用TFreedObject实例替换实际对象。
在这种情况下,obj实际上是一个TFreedObject实例(而不是TStringList)。
obj.InheritsFrom(TStringList) = False
另一方面
(obj is TStringList) = True
因为该代码实际上只会检查nil指针。
PS:无论编译器优化设置如何,生成的代码都是相同的