2013-02-27 50 views
7

考慮下面的代碼提取物:的Delphi:OleVariant和泛型

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

爲什麼啊,爲什麼這個罰款的問題越來越接近票?選民們是否在看他們在投票呢? – 2013-02-27 18:17:01

+0

不用擔心,我們可以隨時重新打開:-) – Johan 2013-02-27 18:41:19

+3

@Johan我們不應該這樣做。 SO的這些審查隊列只是愚蠢的。 – 2013-02-27 19:07:47

回答

8

您的代碼無法編譯,因爲編譯器無法保證在編譯時通用類有可能轉換爲所有可能的T

當泛型方法面臨着

intf.Work(param); 

編譯器需要知道如何param轉換爲OleVariant。而且它不能這樣做。與模板相比,這是泛型的侷限之一。


你最簡單的解決方案是用的幫助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 
hello 
-666