Reputation: 1135
Given the following code:
namespace sample
{
class a { }
class b : a { }
public class wrapper<T> { }
class test
{
void test1()
{
wrapper<a> y = new wrapper<b>();
//Error 11 Cannot implicitly convert type 'sample.wrapper<sample.b>' to 'sample.wrapper<sample.a>'
}
}
}
Logically speaking, a since b
is a
, a wrapper<b>
is a wrapper<a>
. Then why I can't make this conversion, or how can I make it?
Thanks.
Upvotes: 0
Views: 690
Reputation: 30892
Lets do a scenario. Lets call the class a
Mammal
, the class b
Dog
, and lets say that the wrapper<T>
class is List<T>
See what happens in this code
List<Dog> dogs = new List<Dog>(); //create a list of dogs
List<Mammal> mammals = dogs; //reference it as a list of mammals
Cat tabby = new Cat();
mammals.Add(tabby) // adds a cat to a list of dogs (!!?!)
Dog woofer = dogs.First(); //returns our tabby
woofer.Bark(); // and now we have a cat that speaks foreign languages
(Paraphrase of my answer on How to store base class children in a dictionary?)
Upvotes: 0
Reputation: 33139
This is a matter of covariance.
Class b
is an a
, but wrapper<b>
is not a wrapper<a>
.
You can use C# 4's covariance syntax to allow it like so:
public interface IWrapper<out T> { ... }
public class Wrapper<T> : IWrapper<T> { ... }
This will instruct the CLR to see Wrapper<B>
as a Wrapper<A>
.
(For the record: C# has capitalization conventions; class names are Pascal-cased).
Upvotes: 1
Reputation: 37770
since b is a, a
wrapper<b>
is awrapper<a>
Well, this is not true for .NET generic classes, they can't be co-variant. You can achieve something similar using interface covariance:
class a { }
class b : a { }
public interface Iwrapper<out T> { }
public class wrapper<T> : Iwrapper<T> {}
class test
{
void test1()
{
Iwrapper<a> y = new wrapper<b>();
}
}
Upvotes: 3