gpt4 book ai didi

delphi - 为什么没有引发 NullReferenceException?

转载 作者:行者123 更新时间:2023-12-03 15:04:01 28 4
gpt4 key购买 nike

我已经向几位同事展示了这一点,但没有人给出解释。我纯粹偶然遇到了这个问题,因为我以为我在代码中发现了一个错误,但惊讶地发现代码实际上运行了。这是一个简化版本。这已通过 XE-2 完成。

到目前为止,与我交谈过的每个人都希望抛出 NullReferenceException。

 TUnexplainable = class(TObject)
public
function Returns19: Integer;
end;

function TUnexplainable.Returns19: Integer;
begin
Result := 19;
end;

以下测试应该永远不会工作,但它运行成功。为什么没有抛出NullReferenceException???

procedure TTestCNCStep.ShouldNeverEverWorkV4;
var
Impossible: TUnexplainable;
Int1: Integer;
begin
Impossible := nil;
Int1 := Impossible.Returns19; // A Null Reference Exception should ocurr here!!! Instead the method Returns19 is actually invoked!!!!
Check(Int1 = 19);
end;

Test resuts

最佳答案

非静态类方法被编译为带有隐藏 Self 参数的独立函数。因此,从编译器的角度来看,您的代码本质上是在执行以下操作:

//function TUnexplainable.Returns19: Integer;
function TUnexplainable_Returns19(Self: TUnexplainable): Integer;
begin
Result := 19;
end;

//procedure TTestCNCStep.ShouldNeverEverWorkV4;
procedure TTestCNCStep_ShouldNeverEverWorkV4(Self: TTestCNCStep);
var
Impossible: TUnexplainable;
Int1: Integer;
begin
Impossible := nil;
Int1 := TUnexplainable_Returns19(Impossible);
Check(Int1 = 19);
end;

如您所见,Returns19() 没有引用 Self 进行任何操作,因此没有理由发生 nil 指针错误。

更改您的代码以使用 Self 执行某些操作,然后您将看到您期望的错误:

type
TUnexplainable = class(TObject)
public
Number: Integer;
function ReturnsNumber: Integer;
end;

function TUnexplainable.ReturnsNumber: Integer;
begin
Result := Number;
end;

procedure TTestCNCStep.ShouldNeverEverWorkV4;
var
Impossible: TUnexplainable;
Int1: Integer;
begin
Impossible := nil;
Int1 := Impossible.ReturnsNumber; // An EAccessViolation exception will now occur here!!!
end;

I have shown this to several colleagues and no one has an explanation.

我会非常担心与一群同事(假设他们是程序员)一起工作,他们不了解类方法和 Self 参数实际工作原理以及如何调用类方法的基础知识通过nil指针可以避免空指针错误。这就像面向对象编程 101 之类的东西。

关于delphi - 为什么没有引发 NullReferenceException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29479903/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com