问题描述
以下Delphi程序在nil引用后调用method并运行良好。
The following Delphi program calls method upon nil reference and runs fine.
program Project1;
{$APPTYPE CONSOLE}
type
TX = class
function Str: string;
end;
function TX.Str: string;
begin
if Self = nil then begin
Result := 'nil'
end else begin
Result := 'not nil'
end;
end;
begin
Writeln(TX(nil).Str);
Readln;
end.
但是,在结构相似的C#程序中, System.NullReferenceException
将被提高,这似乎是正确的选择。
However, in a structurally similar C# program, System.NullReferenceException
will be raised, which seems to be the right thing to do.
namespace ConsoleApplication1
{
class TX
{
public string Str()
{
if (this == null) { return "null"; }
return "not null";
}
}
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine(((TX)null).Str());
System.Console.ReadLine();
}
}
}
因为是TObject。样式,似乎支持在Delphi中对nil引用调用方法。这是真的 ? (假设在 if Self = nil
分支中,不会访问任何实例字段。)
Because TObject.Free uses such style, it seems to be "supported" to call method on nil reference in Delphi. Is this true ? (Let's suppose that in the if Self = nil
branch, no instance field will be accessed.)
推荐答案
在 nil
引用上调用方法是合理的,但要遵守以下规则:
It is reasonable to call a method on a nil
reference, subject to the following rules:
- 该方法不能是虚拟的或动态的。这是因为虚拟或动态方法是使用引用的运行时类型绑定的。如果引用为
nil
,则没有运行时类型。相比之下,非虚拟,非动态方法在编译时绑定。 - 您可以读取自我,例如将其与
nil
进行比较。 - 如果
Self
为nil
,那么您不能引用任何实例变量。
- The method must not be virtual or dynamic. That is because virtual or dynamic methods are bound using the runtime type of the reference. And if the reference is
nil
then there is no runtime type. By way of contrast, non-virtual, non-dynamic methods are bound at compile time. - You are allowed to read the value of
Self
, for instance to compare it againstnil
. - In case
Self
isnil
, then you must not refer to any instance variables.
这篇关于是否“受支持”?在Delphi中调用nil参考上的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!