私は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が必要ですが、この要件を制約として指定する方法はありません。
一般的な抽象クラスを使用せず、バリデーターにインターフェイスをキャストしないようにすることもできますが、キャストなしでこれを行う方法を知っている人がいるかどうかは不思議です。
仕事に、私は*制約をGUIDた*を指定するためのいくつかの方法があることが必要だと思います。 –