Delphi:OleVariant和泛型

7

请看以下代码片段:

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函数?


2
为什么这个好问题会被投票关闭?投票者是否真正看清了他们所投的内容? - David Heffernan
不用担心,我们总是可以重新打开 :-) - Johan
3
@Johan 我们不应该必须这样做。SO上的这些审查队列太愚蠢了。 - David Heffernan
@DavidHeffernan,在你进行编辑之前,我投票关闭这个问题。原始问题不清楚,也没有发布真正的代码。 - RRUZ
1
@RRUZ 是的,我明白。但是当只有两个投票时,我修复了 Q 的问题。这是盲目的。 - David Heffernan
1个回答

8
你的代码无法编译,因为在泛型类中,编译器无法保证所有可能的 T 都可以进行转换。当遇到这种情况时,
intf.Work(param);

在通用方法中,编译器需要知道如何将param转换为OleVariant。但它无法做到这一点。这是通用性与模板相比的局限之一。
对您来说最简单的解决方案是在运行时使用Rtti单元中的TValue进行转换。
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.

Output

2.4
hello
-666

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接