delphi - 基于无约束泛型类型创建对象实例

标签 delphi generics

我有不受约束的泛型类型 Atomic,它实现了一个初始化程序(详细信息在我的 previous question 中)。

type
  Atomic<T> = class
    type TFactory = reference to function: T;
    class function Initialize(var storage: T; factory: TFactory): T;
  end;

现在我想编写简化的 Initialize 函数,该函数将从 T 获取类型信息(假设 typeof(T) 是 tkClass)并使用默认构造函数创建新实例(必要时)。

遗憾的是,这失败了:

class function Atomic<T>.Initialize(var storage: T): T;
begin
  if not assigned(PPointer(@storage)^) then begin
    if PTypeInfo(TypeInfo(T))^.Kind  <> tkClass then
      raise Exception.Create('Atomic<T>.Initialize: Unsupported type');
    Result := Atomic<T>.Initialize(storage,
      function: T
      begin
        Result := TClass(T).Create; // <-- E2571
      end);
  end;
end;

编译器报告错误E2571类型参数“T”没有类或接口(interface)约束

如何欺骗编译器创建类 T 的实例?

最佳答案

您可以使用GetTypeData获取类引用:

Result := T(GetTypeData(PTypeInfo(TypeInfo(T)))^.ClassType.Create);

在 Delphi XE2 中(希望在下一个版本中),您可以执行以下操作:

var
  xInValue, xOutValue: TValue;

xInValue := GetTypeData(PTypeInfo(TypeInfo(T)))^.ClassType.Create;
xInValue.TryCast(TypeInfo(T), xOutValue);
Result := xOutValue.AsType<T>;

(这种相当规避的方法是由 OmniThreadLibrary 论坛中使用的 cjsalamon 发现的: Error in OtlSync XE2 。)

关于delphi - 基于无约束泛型类型创建对象实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8355456/

相关文章:

ios - Delphi iOS 使用电子邮件导入/导出数据文件

delphi - 如何动态创建与顶部对齐但在其他对齐控件之后的控件?

generics - 如何为返回正确类型的枚举实现 get 方法?

c# - 这些方法线程安全吗?

delphi - FileSize,与这个程序有什么区别以及什么更好用?

windows - 如何在我自己的窗口下捕获屏幕,不包括我自己的窗口

Java泛型可分配性

c# - 通用方法调用重复

c# - 什么是 "Dispatcher"设计模式?

Delphi - 在运行时动态添加所有字段在数据集中生成重复项