Delphi:OleVariant和Generics

时间:2013-02-27 13:20:54

标签: delphi generics

考虑以下代码提取:

type
  MyIntf = interface
    procedure Work(param: OleVariant);
  end;

  MyClass<T> = class
    procedure MyWork(param: T);
  end;

var
  intf: MyIntf;

procedure MyClass<T>.MyWork(param: T);
begin
  //compiler error: E2010 Incompatible types: 'OleVariant' and 'T'
  intf.Work(param);
end;

如上所示,无法使用错误消息进行编译。我如何从我的泛型类中调用Work函数?

1 个答案:

答案 0 :(得分:8)

您的代码无法编译,因为编译器无法在编译时保证泛型类可能转换为所有可能的T

面对

intf.Work(param);

在通用方法中,编译器需要知道如何将param转换为OleVariant。它不能这样做。与模板相比,这是泛型的限制之一。


最简单的解决方案是在TValue单位Rtti的帮助下,在运行时进行转换。

procedure MyClass<T>.MyWork(param: T);
begin
  intf.Work(TValue.From<T>(param).AsVariant);
end;

这是一个示例测试程序,用于演示TValue完成工作:

program SO15113162;
{$APPTYPE CONSOLE}

uses
  Rtti;

procedure Work(param: OleVariant);
begin
  Writeln(param);
end;

type
  MyClass<T> = class
    class procedure MyWork(param: T);
  end;

class procedure MyClass<T>.MyWork(param: T);
begin
  Work(TValue.From<T>(param).AsVariant);
end;

begin
  MyClass<Double>.MyWork(2.4);
  MyClass<string>.MyWork('hello');
  MyClass<Integer>.MyWork(-666);
  Readln;
end.

<强>输出

2.4
hello
-666