泛型类型参数的多个约束的优先级

时间:2014-05-12 22:04:29

标签: c# generics type-constraints

在以下示例中,我在泛型类Foobar中的类型T上有两个约束IFoobar<T>FoobarList<T>。但是编译器给出了一个错误:无法隐式转换类型&#39; Foobar&#39;到了&#39;。存在显式转换(您是否错过了演员?)

interface IFoobar<T>
{
    T CreateFoobar();
}

class Foobar : IFoobar<Foobar>
{
    //some foobar stuffs
    public Foobar CreateFoobar() { return new Foobar(); }
}

class FoobarList<T> where T : Foobar, IFoobar<T>
{
    void Test(T rFoobar)
    {
        T foobar = rFoobar.CreateFoobar(); //error: cannot convert Foobar to T
    }
}

编译器似乎认为CreateFoobar是Foobar中的一种方法,但不是IFoobar中的方法。我可以通过将Foobar划分为基类FoobarBase并在其派生类中实现接口IFoobar来修复编译,如下所示:

interface IFoobar<T>
{
    T CreateFoobar();
}

abstract class FoobarBase
{
    //some foobar stuffs
}

class Foobar : FoobarBase, IFoobar<Foobar>
{
    public Foobar CreateFoobar() { return new Foobar(); }
}

class FoobarList<T> where T : FoobarBase, IFoobar<T>
{
    void Test(T rFoobar)
    {
        T foobar = rFoobar.CreateFoobar();
    }
}

将Foobar分为两类是很麻烦的。有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:4)

只需将rFoobar投射到IFoobar<T>

T foobar = ((IFoobar<T>)rFoobar).CreateFoobar();

这样您就可以调用返回T的方法,而不仅仅是Foobar

正如Rotem建议的那样,更改Foobar中的方法以使用显式接口实现也是有效的:

Foobar IFoobar<Foobar>.CreateFoobar() { return new Foobar(); }

这种方法不会在T中找到,所以它将再次解析为接口方法。