Reputation: 1422
Here's my entire application. To me, this should compile fine.
namespace SampleApp
{
interface I<T> where T : Image
{
}
class A<T> where T : Image
{
}
class B : A<Bitmap>, I<Bitmap>
{
}
class C : A<Metafile>, I<Metafile>
{
}
class Program
{
public static I<Image> SomeProperty { get; set; }
static void Main(string[] args)
{
B b = new B();
SomeProperty = b;
C c = new C();
SomeProperty = c;
}
}
}
However, The lines "SomeProperty = b" and "SomeProperty = c" give the error:
Cannot implicitly convert type 'B' to 'I<System.Drawing.Image>'. An explicit conversion exists (are you missing a cast?)
But I can't work out why. B implements I<Bitmap>
, and Bitmap is a subclass of Image, so surely, by definition, B implements I<Image>
.
Upvotes: 1
Views: 646
Reputation: 1500155
As Sasha says, you're looking for generic covariance. This may or may not be appropriate depending on what your interface members look like. If you only ever take values "out" of the interface, you can make your code compile by making T
covariant:
interface I<out T> where T : Image
{
}
However, if you have any methods accepting T
, e.g.
void ReplaceWith(T newImage)
then you can't make T
covariant.
Generic variance is a complicated topic - I gave a talk at NDC 2010 which you may find useful. You can watch it at the NDC video site. Search for "variance" to find it quickly. (The real content starts at about 2 minutes.)
Upvotes: 3
Reputation: 30830
Change your interface to following to make it work:
interface I<out T> where T : Image
{
}
It is called Covariance
. Read following link for more information:
Covariance and Contravariance FAQ
Upvotes: 1
Reputation: 3519
No, it doesn't work that way with generics. A may be a subclass of B, but G<A>
is not a subclass of G<B>
. The same goes for interfaces.
You might be looking for a feature called generic covariance/contravariance, but to determine if you can use it in this case you would need to show us the real contents of the interface.
Upvotes: 2