✅ Covariance & Contravariance
public interface IRepository<T>
{
T Get();
void Add(T item);
}
public class Animal
{
public string Name { get; set; }
}
public class Dog : Animal
{
public string Breed { get; set; }
}
public class AnimalRepository : IRepository<Animal>
{
public Animal Get()
{
Console.WriteLine("Getting an animal from the repository.");
return new Animal { Name = "Fido" };
}
public void Add(Animal item)
{
Console.WriteLine("Adding an animal to the repository.");
}
}
public class DogRepository : IRepository<Dog>
{
public Dog Get()
{
Console.WriteLine("Getting a dog from the repository.");
return new Dog { Name = "Buddy", Breed = "Golden Retriever" };
}
public void Add(Dog item)
{
Console.WriteLine("Adding a dog to the repository.");
}
}
internal class Program
{
public static void UseAnimalRepository(IRepository<Animal> repository)
{
var animal = repository.Get();
Console.WriteLine("Used repository to get an animal: " + animal.Name);
repository.Add(new Animal { Name = "Spot" });
Console.WriteLine("Used repository to add an animal.");
}
public static void Main()
{
AnimalRepository animalRepository = new AnimalRepository();
DogRepository dogRepository = new DogRepository();
Console.WriteLine("Using Animal Repository:");
UseAnimalRepository(animalRepository);
Console.WriteLine("\nUsing Dog Repository:");
UseAnimalRepository(dogRepository); // This line won't work without contravariance
}
} public interface IRepository<T>
{
T Get();
void Add(T item);
}
public class Animal
{
public string Name { get; set; }
}
public class Dog : Animal
{
public string Breed { get; set; }
}
public class AnimalRepository : IRepository<Animal>
{
public Animal Get()
{
Console.WriteLine("Getting an animal from the repository.");
return new Animal { Name = "Fido" };
}
public void Add(Animal item)
{
Console.WriteLine("Adding an animal to the repository.");
}
}
public class DogRepository : IRepository<Dog>
{
public Dog Get()
{
Console.WriteLine("Getting a dog from the repository.");
return new Dog { Name = "Buddy", Breed = "Golden Retriever" };
}
public void Add(Dog item)
{
Console.WriteLine("Adding a dog to the repository.");
}
}
internal class Program
{
public static void UseAnimalRepository(IRepository<Animal> repository)
{
var animal = repository.Get();
Console.WriteLine("Used repository to get an animal: " + animal.Name);
repository.Add(new Animal { Name = "Spot" });
Console.WriteLine("Used repository to add an animal.");
}
public static void Main()
{
AnimalRepository animalRepository = new AnimalRepository();
DogRepository dogRepository = new DogRepository();
Console.WriteLine("Using Animal Repository:");
UseAnimalRepository(animalRepository);
Console.WriteLine("\nUsing Dog Repository:");
UseAnimalRepository(dogRepository); // This line won't work without contravariance
}
}So i wrote up this example and I stumbled upon the contravariance lacking here.