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分为两类是很麻烦的.有没有更好的方法来解决这个问题?
只需投射rFoobar到IFoobar<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,因此它将再次解析为接口方法。