【发布时间】:2021-08-31 08:02:12
【问题描述】:
我使用 Delphi 10.3。我有两种方法实现,用于将枚举类型转换回和 fort 为字符串。这不是真正的实现,只是服务本质的两个变体:
案例一:
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/GetValue 在TMyClass 实现中工作正常,但在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 );)
【问题讨论】:
-
您的 IMyInterface 声明是什么?您的 TMyClass 无法编译并出现相同的错误。您需要在通话中使用 getValue
和 getName 。 -
@DalijaPrasnikar IMyInterface
就像在实现中一样声明 asString和fromString。我把它放到代码示例中。你说的对!我刚刚成功测试了TMyClass.asString和getName,并且我假设'TMyClass.fromString也可以编译。但它会导致与接口实现中相同的错误消息。它变得越来越陌生。一种 TRTTIEnumerationType 方法调用有效,另一种无效。 -
@DalijaPrasnikar 将您的 getValue
和 getName 评论转换为答案,我会接受。令人惊讶的是,我应该打电话给 TRTTIEnumerationTypee.getName<T>( value_ )而不是TRTTIEnumerationTypee.getName( value_ );。感谢您的回答。