Delphi 如果未设置属性,则生成编译器错误
如果未设置对象中的某个属性,我希望能够创建编译器错误/警告。假设我有以下课程:Delphi 如果未设置属性,则生成编译器错误,delphi,firemonkey,delphi-10-seattle,Delphi,Firemonkey,Delphi 10 Seattle,如果未设置对象中的某个属性,我希望能够创建编译器错误/警告。假设我有以下课程: interface type TBarkevent = procedure (Bark : String) of object; TDog = class private FOnBark : TBarkevent; procedure SetBark(const Value: TBarkevent); function GetBark: TBarkEvent; public
interface
type
TBarkevent = procedure (Bark : String) of object;
TDog = class
private
FOnBark : TBarkevent;
procedure SetBark(const Value: TBarkevent);
function GetBark: TBarkEvent;
public
procedure Bark;
property OnBark : TBarkEvent read GetBark write SetBark;
constructor Create;
end;
implementation
{ TDog }
procedure TDog.Bark;
begin
if Assigned(OnBark) then
OnBark('Woof!')
end;
constructor TDog.Create;
begin
end;
function TDog.GetBark: TBarkEvent;
begin
Result := FOnBark;
end;
procedure TDog.SetBark(const Value: TBarkevent);
begin
FOnBark := Value;
end;
我在另一个单元中使用TDog
类,如下所示:
var
Dog : TDog;
begin
Dog := TDog.Create;
Dog.OnBark := DogBark;
Dog.Bark;
现在,一旦调用Bark()
过程,就会触发OnBark
事件
我的问题:
我是否可以强制指定OnBark
属性,以便在未设置事件时发出编译器错误/警告?将类定义为:
TDog = class
private
FOnBark : TBarkevent;
procedure SetBark(const Value: TBarkevent);
function GetBark: TBarkEvent;
public
procedure Bark;
property OnBark : TBarkEvent read GetBark write SetBark;
constructor Create(Bark : TBarkEvent);
end;
这样,如果不指定事件,就无法实例化
TDog
对象。如果您尝试,您将得到一个编译器错误。首先:否。不可能在编译时检查这样的属性
要使几乎成为强制执行OnBark
事件的,可以将其添加为构造函数参数,而不是将其作为读/写属性发布。然后,在调用构造函数时,可以使用Assert()
在运行时检查是否已将有效的回调方法传递给构造函数
要使其真正成为强制性的,您可以声明以下内容:
TCustomDog = class
public
procedure Bark; virtual; abstract;
end;
因此,每个使用
TCustomDog
类的人都必须实现Bark
过程。如果他不这样做,编译器将发出警告。只是澄清一下:构造函数方法将生成错误。抽象方式(默认情况下)只会生成警告。。。因此(依我看)构造函数方式将是更好的选择。@kobik:它不是。代码必须从TCustomDog
派生另一个类,并用具体的实现替代Bark()
,而不是使用事件。@HeartWare这是正确的。我自己也会选择构造函数的方式。是的,但是事件仍然可以被分配一个nil
值,这不满足OP的要求。同意@RemyLebeau,但是可以在构造函数中检查nil,并在其中引发异常case@RemyLebeau:为什么不呢?赋值为零仍然是赋值。在Bark方法中甚至有一个关于值是否为非NIL的检查,因此(对我来说)NIL值显然是一个有效值。如果没有,则Bark方法应该只调用FOnBark事件,如果没有为其指定非NIL值,则让它崩溃。如果NIL不是一个有效值,那么应该在构造函数中执行检查,并删除Bark方法中的检查。有时,你必须站到最前面,把事情做好。“编译器不能帮你完成你的工作。@DavidHeffernan问题是,几年后,除了我以外的其他人可能会使用此代码,并有一些东西告诉他们他们在早期犯了错误,这可以节省大量时间和精力,这被称为documentationIndeed,Dog.ScratchEar代码>不会为您带来任何魔力:-)