Reputation: 315
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?
Upvotes: 6
Views: 151
Reputation: 1502835
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.
Upvotes: 4