2016-01-21 91 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'。我修改了答案。 –

相关问题