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

Time:09-17

I use Delphi 10.3. I have two kind of method implementation for converting enumeration types back and fort to string. This is not the real implementation just two variants for the essence of the service:

Case 1:

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;

Case2:

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;

The TRTTIEnumeration.GetName/GetValue works fine in TMyClass implementation but does not compile in the TMyInterfaceImpl<T>:

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

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

But I want to implement this service as an interface. Is there any solution to do that with the TMyInterfaceImpl<T>? The generic type parameterized methods are not allowed in Interfaces. (procedure foo<T>( const value_ : T );)

CodePudding user response:

GetName and GetValue class functions in TRTTIEnumerationType are parameterized functions:

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

You need to add T when you call them GetName<T>(...) and GetValue<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;
  • Related