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

本文关键字:优先级 约束 泛型类型参数 | 更新日期: 2023-09-27 18:03:13

在下面的例子中,我有两个约束,FoobarIFoobar<T>,在泛型类FoobarList<T>的类型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
    }
}

似乎编译器认为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分为两类比较麻烦。有更好的解决办法吗?

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

rFoobar转换为IFoobar<T>:

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

这样你调用的方法返回T而不仅仅是Foobar

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

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

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