我想创建一个通用的Subject Interface,因此将它重用于“specifics”Observer类。所以我为主题尝试了这个代码:
unit uISubject;
interface
type
ISubject = interface(IInterface)
procedure RegisterObserver(Observer: IInterface);
procedure RemoveObserver(Observer: IInterface);
procedure NotifyObservers;
end;
implementation
end.
我有以下观察员课程:
串行通信观察器
unit uISerialObserver;
interface
type
ISerialObserver = interface(IInterface)
['{EF833BD7-31C1-49B3-8041-F1574AC043F0}']
procedure DataAvailable(ReceivedData: AnsiString);
end;
implementation
end.
更新进度条的观察者
unit uIProgressObserver;
interface
type
IProgressObserver = interface(IInterface)
['{05AC7C76-CD41-42AB-B793-1512E68D91D5}']
procedure UpdateProgressParameters(Min, Max: Cardinal);
procedure IncrementParameter;
end;
implementation
end.
我已经实现了这样的Notify方法:
procedure TSerialPortCommunicator.NotifyObservers;
var
Obs: IInterface;
begin
for Obs in FObservers do
begin
ISerialObserver(Obs).UpdateObserver(FReceivedData);
end;
end;
,其中
FObservers: TList<IInterface>;
当NotifyObservers
运行时,Delphi会返回访问冲突错误。
我想知道我做错了什么?
答案 0 :(得分:2)
您需要使用as
运算符强制转换界面。
您的代码ISerialObserver(IInterface(Obs))
是一个特定的失败点。你应该写Obs as ISerialObserver
。但为什么不制作你的列表TList<ISerialObserver>
,从而避免演员?
那就是说,你确定列表中的所有内容都实现了ISerialObserver
吗?这些摘录并不明显。您可以使用is
运算符或更实用的Supports()
函数来检查界面支持。
此外,您不需要从IInterface继承,这是隐式的。因此,您可以将ISubject = interface(IInterface)
替换为ISubject = interface
,依此类推。