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

前端之家收集整理的这篇文章主要介绍了delphi – 如何将对象转换为泛型?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试将返回的基础对象强制转换为它的特定泛型类型.我认为下面的代码应该工作,但会产生内部编译器错误,还有另一种方法吗?
  1. type
  2. TPersistGeneric<T> = class
  3. private
  4. type
  5. TPointer = ^T;
  6. public
  7. class function Init : T;
  8. end;
  9.  
  10. class function TPersistGeneric<T>.Init : T;
  11. var
  12. o : TXPersistent; // root class
  13. begin
  14. case PTypeInfo(TypeInfo(T))^.Kind of
  15. tkClass : begin
  16. // xpcreate returns txpersistent,a root class of T
  17. o := XPCreate(GetTypeName(TypeInfo(T))); // has a listed of registered classes
  18. result := TPointer(pointer(@o))^;
  19. end;
  20. else
  21. result := Default(T);
  22. end;
  23. end;

解决方法

我正在使用一个类型转换辅助类来执行类型转换,并检查这两个类是否兼容.
  1. class function TPersistGeneric<T>.Init: T;
  2. var
  3. o : TXPersistent; // root class
  4. begin
  5. case PTypeInfo(TypeInfo(T))^.Kind of
  6. tkClass : begin
  7. // xpcreate returns txpersistent,a root class of T
  8. o := XPCreate(GetTypeName(TypeInfo(T))); // has a listed of registered classes
  9. Result := TTypeCast.DynamicCast<TXPersistent,T>(o);
  10. end;
  11. else
  12. result := Default(T);
  13. end;

这是班级:

  1. type
  2. TTypeCast = class
  3. public
  4. // ReinterpretCast does a hard type cast
  5. class function ReinterpretCast<ReturnT>(const Value): ReturnT;
  6. // StaticCast does a hard type cast but requires an input type
  7. class function StaticCast<T,ReturnT>(const Value: T): ReturnT;
  8. // DynamicCast is like the as-operator. It checks if the object can be typecasted
  9. class function DynamicCast<T,ReturnT>(const Value: T): ReturnT;
  10. end;
  11.  
  12. class function TTypeCast.ReinterpretCast<ReturnT>(const Value): ReturnT;
  13. begin
  14. Result := ReturnT(Value);
  15. end;
  16.  
  17. class function TTypeCast.StaticCast<T,ReturnT>(const Value: T): ReturnT;
  18. begin
  19. Result := ReinterpretCast<ReturnT>(Value);
  20. end;
  21.  
  22. class function TTypeCast.DynamicCast<T,ReturnT>(const Value: T): ReturnT;
  23. var
  24. TypeT,TypeReturnT: PTypeInfo;
  25. Obj: TObject;
  26. LClass: TClass;
  27. ClassNameReturnT,ClassNameT: string;
  28. FoundReturnT,FoundT: Boolean;
  29. begin
  30. TypeT := TypeInfo(T);
  31. TypeReturnT := TypeInfo(ReturnT);
  32. if (TypeT = nil) or (TypeReturnT = nil) then
  33. raise Exception.Create('Missing Typeinformation');
  34. if TypeT.Kind <> tkClass then
  35. raise Exception.Create('Source type is not a class');
  36. if TypeReturnT.Kind <> tkClass then
  37. raise Exception.Create('Destination type is not a class');
  38.  
  39. Obj := TObject(Pointer(@Value)^);
  40. if Obj = nil then
  41. Result := Default(ReturnT)
  42. else
  43. begin
  44. ClassNameReturnT := UTF8ToString(TypeReturnT.Name);
  45. ClassNameT := UTF8ToString(TypeT.Name);
  46. LClass := Obj.ClassType;
  47. FoundReturnT := False;
  48. FoundT := False;
  49. while (LClass <> nil) and not (FoundT and FoundReturnT) do
  50. begin
  51. if not FoundReturnT and (LClass.ClassName = ClassNameReturnT) then
  52. FoundReturnT := True;
  53. if not FoundT and (LClass.ClassName = ClassNameT) then
  54. FoundT := True;
  55. LClass := LClass.ClassParent;
  56. end;
  57. //if LClass <> nil then << TObject doesn't work with this line
  58. if FoundT and FoundReturnT then
  59. Result := ReinterpretCast<ReturnT>(Obj)
  60. else
  61. if not FoundReturnT then
  62. raise Exception.CreateFmt('Cannot cast class %s to %s',[Obj.ClassName,ClassNameReturnT])
  63. else
  64. raise Exception.CreateFmt('Object (%s) is not of class %s',ClassNameT]);
  65. end;
  66. end;

猜你在找的Delphi相关文章