【发布时间】:2011-10-27 20:28:46
【问题描述】:
我正在使用 Delphi XE2。目前我有一个基于对象的模型,每个模型对象可以有多个验证器。这是验证器通用抽象类的简化实现。具体的验证器类可以覆盖 DoValidate 并且它们不必强制转换模型对象。验证器通过其 IValidator 接口使用。
unit ObjectBasedValidator;
interface
uses
System.SysUtils,
System.Generics.Collections;
type
TModelEntity = class
end;
type
IValidator = interface
procedure Validate(aEntity: TModelEntity; aResult: string);
end;
TValidator<T: TModelEntity> = class(TInterfacedObject, IValidator)
private
protected
procedure DoValidate(aEntity: T; aResult: string); virtual; abstract;
public
procedure Validate(aEntity: TModelEntity; aResult: string);
end;
implementation
{ TValidator<T> }
procedure TValidator<T>.Validate(aEntity: TModelEntity; aResult: string);
begin
if not (aEntity is T) then
Exit;
DoValidate(aEntity as T, aResult);
end;
end.
现在我正在尝试将对象模型更改为基于接口。所以这里是更新的验证器单元:
unit InterfaceBasedValidator;
interface
type
IModelEntity = interface
end;
type
IValidator = interface
procedure Validate(aEntity: IModelEntity; aResult: string);
end;
TValidator<I: IModelEntity> = class(TInterfacedObject, IValidator)
private
protected
procedure DoValidate(aEntity: I; aResult: string); virtual; abstract;
public
procedure Validate(aEntity: IModelEntity; aResult: string);
end;
implementation
{ TValidator<T> }
procedure TValidator<I>.Validate(aEntity: IModelEntity; aResult: string);
begin
// The next line does not compiles
if not (aEntity is I) then
Exit;
DoValidate(aEntity as I, aResult);
end;
end.
我对无法编译的行添加了注释。现在显然“I”泛型类型需要定义一个 GUID 才能工作,但是没有办法将此要求指定为约束。
一种可能的解决方法是不使用通用抽象类并在验证器中强制转换接口,但我只是想知道是否有人知道如何在不强制转换的情况下做到这一点。
【问题讨论】:
-
为此,我认为需要某种方式来指定 has GUID 约束。