abstract class Pet : Animal {}
interface ICageIn<in T> { T content { set; } }
interface ICageOut<out T> { T content { get; } }
interface ICageInOut<T> { T content { get; set; } }
class Cage<T> : ICageIn<T>, ICageOut<T>, ICageInOut<T> { public T content { get; set; } }
static void touchPet( ICageOut<Pet> cage ) {
Console.WriteLine( cage.content );
static void pushPet( ICageIn<Pet> cage ) {
cage.content = new Dog();
static void replacePet( ICageInOut<Pet> cage ) {
touchPet( cage as ICageOut<Pet> );
pushPet( cage as ICageIn<Pet> );
void enshurePet( Cage<Pet> cage ) {
if( cage.content is Pet ) return;
pushPet( cage as ICageIn<Pet> );
public static void Main() {
var animalCage = new Cage<Animal>();
var petCage = new Cage<Pet>();
var catCage = new Cage<Cat>();
var dogCage = new Cage<Dog>();
var foxCage = new Cage<Fox>();
replacePet( animalCage );