【问题标题】:Action as generic type in constructor gives compile error构造函数中作为泛型类型的操作会产生编译错误
【发布时间】:2016-01-21 11:23:33
【问题描述】:

为什么Funky<T> 中的构造函数重载有action 参数的问题,而子类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
    {
    }
}

【问题讨论】:

  • 因为 action != T 在您的基类中。 T 可以是任何东西。在您的派生类中,T 是一个 Action

标签: c# .net generics delegates


【解决方案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)

正在尝试使用这个基类构造函数:

 public Funky(T action)

但是由于它定义TAction(在class FunkyAction : Funky&lt;Action&gt;中),那么基础构造函数实际上是这样的(从FunkyAction的角度来看):

public Funky(Action action)

现在将Action 类型的参数传递给需要Action 的方法没有问题。

你可以像这样使基类构造函数通用:

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

这将允许您创建一个 Funky&lt;Action&gt; 并使用 Action 构造它,如下所示:

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

【讨论】:

  • 好的,是的 - constraints 解释很有用。我曾经使用 C++(几年前!),我想我曾经一度混淆了这两种语言。
  • @mungflesh,请注意,您不能将T 的约束指定为Action。我修改了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多