In the following example, I have two constraints, Foobar and IFoobar<T>, on type T in generic class FoobarList<T>. But the compiler gives an error: Cannot implicitly convert type 'Foobar' to 'T'. An explicit conversion exists (are you missing a cast?)
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
}
}
It seems the compiler considers CreateFoobar as a method in Foobar, but not the one in IFoobar. I can fix the compile by dividing Foobar into a base class FoobarBase, and implementing the interface IFoobar in its derived class, as follows:
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();
}
}
It is cumbersome to divide Foobar into two classes. Is there a better way to fix this?

Just cast rFoobar to IFoobar<T>:
T foobar = ((IFoobar<T>)rFoobar).CreateFoobar();
That way you're calling a method that returns T rather than just Foobar.
As Rotem suggests, changing the method in Foobar to use explicit interface implementation works too:
Foobar IFoobar<Foobar>.CreateFoobar() { return new Foobar(); }
That way that method won't be found in T, so again it will resolve to the interface method.
See more on this question at Stackoverflow