2016-01-21 69 views
2

爲什麼Funky<T>中的構造函數過載與參數動作有關,但子類FunkyAction沒有?作爲構造函數中的泛型類型給出了編譯錯誤

class Funky<T> 
{ 
    readonly T _data; 

    public Funky(T data) 
    { 
     _data = data; 
    } 

    public Funky(Action action, bool imJustAnOverload) 
     : this(action) // cannot convert from 'System.Action' to 'T' 
    { 
    } 
} 


class FunkyAction : Funky<Action> 
{ 
    public FunkyAction(Action action) 
     : base(action) // no compile error 
    { 
    } 
} 
+2

因爲'action'! ='T'在你的基類中。 'T'可以是任何東西。在你的派生類中'T'是一個'Action'。 –

回答

1

此構造:

public Funky(Action action, bool imJustAnOverload) 
    : this(action) 

嘗試使用此構造函數:

public Funky(T data) 

傳遞一個Action作爲參數T類型的參數。

由於T是一個通用類型的參數表,因此編譯器不能保證action可以被鑄造到T。就編譯器而言,T可能是intstring

現在,派生類,這個構造:

public FunkyAction(Action action) 
    : base(action) 

嘗試使用這個基類的構造函數:

但由於它是定義TAction(在class FunkyAction : Funky<Action>)那麼基礎構造函數實際上看起來像這樣(從具體的FunkyAction的角度看):

public Funky(Action action) 

現在將Action類型的參數傳遞給期望Action的方法沒有任何問題。

你可以使基類的構造一般是這樣的:

public Funky(T action, bool imJustAnOverload) 
     : this(action) 
    { 
    } 

這將允許您創建一個Funky<Action>並與Action這樣的構造是:

Funky<Action> funky = new Funky<Action>(() => DoSomething(), true); 
+0

好的,是的 - _constraints_解釋很有用。我曾經使用過C++(幾年前!),我認爲我一時混淆了這兩種語言。 – mungflesh

+0

@mungflesh,請注意,你不能爲'T'指定一個約束作爲'Action'。我修改了答案。 –

相關問題