gpt4 book ai didi

delphi - 如何将对象转换为泛型?

转载 作者:行者123 更新时间:2023-12-03 14:50:46 25 4
gpt4 key购买 nike

我正在尝试将返回的基础对象转换为其特定的泛型类型。我认为下面的代码应该可以工作,但会生成内部编译器错误,还有其他方法可以做到这一点吗?

type
TPersistGeneric<T> = class
private
type
TPointer = ^T;
public
class function Init : T;
end;

class function TPersistGeneric<T>.Init : T;
var
o : TXPersistent; // root class
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkClass : begin
// xpcreate returns txpersistent, a root class of T
o := XPCreate(GetTypeName(TypeInfo(T))); // has a listed of registered classes
result := TPointer(pointer(@o))^;
end;
else
result := Default(T);
end;
end;

最佳答案

我正在使用一个类型转换辅助类来执行类型转换并检查这两个类是否兼容。

class function TPersistGeneric<T>.Init: T;
var
o : TXPersistent; // root class
begin
case PTypeInfo(TypeInfo(T))^.Kind of
tkClass : begin
// xpcreate returns txpersistent, a root class of T
o := XPCreate(GetTypeName(TypeInfo(T))); // has a listed of registered classes
Result := TTypeCast.DynamicCast<TXPersistent, T>(o);
end;
else
result := Default(T);
end;

这是类(class):

type
TTypeCast = class
public
// ReinterpretCast does a hard type cast
class function ReinterpretCast<ReturnT>(const Value): ReturnT;
// StaticCast does a hard type cast but requires an input type
class function StaticCast<T, ReturnT>(const Value: T): ReturnT;
// DynamicCast is like the as-operator. It checks if the object can be typecasted
class function DynamicCast<T, ReturnT>(const Value: T): ReturnT;
end;

class function TTypeCast.ReinterpretCast<ReturnT>(const Value): ReturnT;
begin
Result := ReturnT(Value);
end;

class function TTypeCast.StaticCast<T, ReturnT>(const Value: T): ReturnT;
begin
Result := ReinterpretCast<ReturnT>(Value);
end;

class function TTypeCast.DynamicCast<T, ReturnT>(const Value: T): ReturnT;
var
TypeT, TypeReturnT: PTypeInfo;
Obj: TObject;
LClass: TClass;
ClassNameReturnT, ClassNameT: string;
FoundReturnT, FoundT: Boolean;
begin
TypeT := TypeInfo(T);
TypeReturnT := TypeInfo(ReturnT);
if (TypeT = nil) or (TypeReturnT = nil) then
raise Exception.Create('Missing Typeinformation');
if TypeT.Kind <> tkClass then
raise Exception.Create('Source type is not a class');
if TypeReturnT.Kind <> tkClass then
raise Exception.Create('Destination type is not a class');

Obj := TObject(Pointer(@Value)^);
if Obj = nil then
Result := Default(ReturnT)
else
begin
ClassNameReturnT := UTF8ToString(TypeReturnT.Name);
ClassNameT := UTF8ToString(TypeT.Name);
LClass := Obj.ClassType;
FoundReturnT := False;
FoundT := False;
while (LClass <> nil) and not (FoundT and FoundReturnT) do
begin
if not FoundReturnT and (LClass.ClassName = ClassNameReturnT) then
FoundReturnT := True;
if not FoundT and (LClass.ClassName = ClassNameT) then
FoundT := True;
LClass := LClass.ClassParent;
end;
//if LClass <> nil then << TObject doesn't work with this line
if FoundT and FoundReturnT then
Result := ReinterpretCast<ReturnT>(Obj)
else
if not FoundReturnT then
raise Exception.CreateFmt('Cannot cast class %s to %s',
[Obj.ClassName, ClassNameReturnT])
else
raise Exception.CreateFmt('Object (%s) is not of class %s',
[Obj.ClassName, ClassNameT]);
end;
end;

关于delphi - 如何将对象转换为泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/924659/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com