I am trying to learn how to create generic classes with c#. Can someone explain why I get a compile error when I run this program.
I have created the IZooAnimal interface. All zoo animals will implement this interface.
public interface IZooAnimal
{
string Id { get; set; }
}
public class Lion : IZooAnimal
{
string Id { get; set; }
}
public class Zebra : IZooAnimal
{
public string Id { get; set; }
}
The ZooCage will hold animals of the same Type
public class ZooCage<T> where T : IZooAnimal
{
public IList<T> Animals { get; set; }
}
The zoo class have cages
public class Zoo
{
public IList<ZooCage<IZooAnimal>> ZooCages { get; set; }
}
The program that uses the classes
class Program
{
static void Main(string[] args)
{
var lion = new Lion();
var lionCage = new ZooCage<Lion>();
lionCage.Animals = new List<Lion>();
lionCage.Animals.Add(lion);
var zebra = new Zebra();
var zebraCage = new ZooCage<Zebra>();
zebraCage.Animals = new List<Zebra>();
zebraCage.Animals.Add(zebra);
var zoo = new Zoo();
zoo.ZooCages = new List<ZooCage<IZooAnimal>>();
zoo.ZooCages.Add(lionCage);
}
}
When I compile I get the following error:
Error 2 Argument 1: cannot convert from 'ConsoleApplication2.ZooCage<ConsoleApplication2.Lion>
' to 'ConsoleApplication2.ZooCage<ConsoleApplication2.IZooAnimal>
'
What changes do I have to do in order to make my program run?
@DanielMann's answer is quite good, but suffers from one drawback: the original IList
interface cannot be used with the ICage
interface. Instead, the ICage has to expose a ReadOnlyCollection, and expose a new method called CageAnimal.
I've also re-written the code using a similar approach. My ICage
implementation is much weaker, but it allows you to stick with IList
semantics inside.
public interface IZooAnimal
{
string Id { get; set; }
}
public class Lion : IZooAnimal
{
public string Id { get; set; }
}
public class Zebra : IZooAnimal
{
public string Id { get; set; }
}
public interface ICage
{
IEnumerable<IZooAnimal> WeaklyTypedAnimals { get; }
}
public class Cage<T> : ICage where T : IZooAnimal
{
public IList<T> Animals { get; set; }
public IEnumerable<IZooAnimal> WeaklyTypedAnimals
{
get { return (IEnumerable<IZooAnimal>) Animals; }
}
}
public class Zoo
{
public IList<ICage> ZooCages { get; set; }
}
class Program
{
static void Main(string[] args)
{
var lion = new Lion();
var lionCage = new Cage<Lion>();
lionCage.Animals = new List<Lion>();
lionCage.Animals.Add(lion);
var zebra = new Zebra();
var zebraCage = new Cage<Zebra>();
zebraCage.Animals = new List<Zebra>();
zebraCage.Animals.Add(zebra);
var zoo = new Zoo();
zoo.ZooCages = new List<ICage>();
zoo.ZooCages.Add(lionCage);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With