E2010 不兼容的类型:'System.Rtti.T' 和 'MyInterfaceImpl.T' 泛型

E2010 Incompatible types: 'System.Rtti.T' and 'MyInterfaceImpl.T' generic

我用的是Delphi10.3。我有两种用于将枚举类型转换回和转换为字符串的方法实现。这不是真正的实现,只是服务本质的两个变体:

案例一:

TMyClass = class
  private
    ctx : TRTTIContext;
  public
    function asString<T>( const value_ : T ) : string;
    function fromString<T>( const value_ : string ) : T;
end;

function TMyClass.asString<T>( const value_ : T ) : string;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getName( value_ );
  end;
end;

function TMyClass.fromString<T>( const value_ : string ) : T;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getValue( value_ );
  end;
end;

案例2:

IMyInterface<T> = interface
  ['{C03754B7-2225-4EB5-97C1-9820B3D1EBAD}']
  function asString( const value_ : T ) : string;
  function fromString( const value_ : string ) : T;
end;

TMyInterfaceImpl<T> = class ( TInterfacedObject, IMyInterface<T> )
  private
    ctx : TRTTIContext;
  public
    function asString( const value_ : T ) : string;
    function fromString( const value_ : string ) : T;
end;

function TMyInterfaceImpl<T>.asString( const value_ : T ) : string;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getName( value_ );
  end;
end;

function TMyInterfaceImpl<T>.fromString( const value_ : string ) : T;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getValue( value_ );
  end;
end;

TRTTIEnumeration.GetName/GetValueTMyClass 实现中工作正常,但在 TMyInterfaceImpl<T> 中无法编译:

E2010 Incompatible types: 'System.Rtti.T' and 'MyInterfaceImpl.T'

E2531 Method 'GetValue' requires explicit type argument(s)

但我想将此服务实现为一个接口。 TMyInterfaceImpl<T> 有解决办法吗?接口中不允许使用泛型参数化方法。 (procedure foo<T>( const value_ : T );)

GetNameGetValueclass函数在TRTTIEnumerationType中是参数化函数:

class function GetName<T{: enum}>(AValue: T): string; reintroduce; static;
class function GetValue<T{: enum}>(const AName: string): T; static;

调用GetName<T>(...)GetValue<T>(...)

时需要加上T
function TMyInterfaceImpl<T>.asString( const value_ : T ) : string;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getName<T>( value_ );
  end;
end;

function TMyInterfaceImpl<T>.fromString( const value_ : string ) : T;
var
  rttiType : TRTTIType;
begin
  rttiType := ctx.getType( typeInfo( T ) );
  if ( rttiType.typeKind = tkEnumeration ) then
  begin
    result := TRTTIEnumerationType( rttiType ).getValue<T>( value_ );
  end;
end;