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

Fan*_*Fan 6 c# generics type-constraints

在下面的示例中,我有两个约束,Foobar并且IFoobar<T>在泛型类中的类型T上FoobarList<T>.但是编译器给出了一个错误:无法将类型'Foobar'隐式转换为'T'.存在显式转换(您是否错过了演员?)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来编译器认为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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 4

只需投射rFoobarIFoobar<T>

T foobar = ((IFoobar<T>)rFoobar).CreateFoobar();
Run Code Online (Sandbox Code Playgroud)

这样你就可以调用一个返回的方法而T不仅仅是Foobar.

正如 Rotem 所建议的,将方法更改为Foobar使用显式接口实现也是可行的:

Foobar IFoobar<Foobar>.CreateFoobar() { return new Foobar(); }
Run Code Online (Sandbox Code Playgroud)

这样就不会在 中找到该方法T,因此它将再次解析为接口方法。