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ジェネリッククラスから関数を呼び出すにはどうすればよいですか?

4

1 に答える 1

8

コンパイラは、ジェネリッククラスのコンパイル時に、考えられるすべてのに変換される可能性があることを保証できないため、コードのコンパイルに失敗しますT

直面したとき

intf.Work(param);

param一般的な方法では、コンパイラはに変換する方法を知る必要がありますOleVariant。そして、それはできません。これは、テンプレートと比較したジェネリックの制限の1つです。


あなたにとって最も簡単な解決策はTValueRttiユニットの助けを借りて実行時に変換を行うことです。

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
こんにちは
-666
于 2013-02-27T13:34:48.670 に答える