Skip to content

Instantly share code, notes, and snippets.

@waf
Last active February 7, 2017 01:57
Show Gist options
  • Save waf/b39e3c71bab1198d8d7603c66675ec66 to your computer and use it in GitHub Desktop.
Save waf/b39e3c71bab1198d8d7603c66675ec66 to your computer and use it in GitHub Desktop.
Covariance and Contravariance
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public void Main(string[] args)
{
Apple apple = new Apple();
Orange orange = new Orange();
Fruit fruit = new Apple();
// covariance (out)
// VALID - data only comes "out" of IEnumerable<out T>
{
IEnumerable<Fruit> fruitEnumerable = new List<Apple> { apple };
Fruit first = fruitEnumerable.First(); // fine if it's an apple!
}
// contravariance (in)
// VALID - data only goes "in" to the parameter of Func<in T, out TResult>
{
Func<Apple, object> appleFunction = (appleParam) => appleParam.MakeAppleJuice() ?? appleParam.Eat();
Func<Fruit, object> fruitFunction = (fruitParam) => fruitParam.Eat();
appleFunction = fruitFunction;
appleFunction(apple); // ok because fruitFunction works on apples
}
// covariance (out)
// COMPILE ERROR - not logical! Data can go in and come out of IList<T> (.Add and .First).
{
IList<Fruit> fruitList = new List<Apple>();
fruitList.Add(new Orange()); // adding an orange, when the underlying collection only suppots apples!
}
// contravariance (in)
// COMPILE ERROR - not logical! Data can come out of the Func<in T, out TResult> as return values.
{
Func<object, Apple> appleFunction = (_) => apple;
Func<object, Fruit> fruitFunction = (_) => orange;
appleFunction(apple);
fruitFunction(fruit);
// BOOM
appleFunction = fruitFunction;
Apple appleReturn = appleFunction(null); // oh no an Orange!
}
}
public abstract class Fruit
{
public object Eat() => null;
}
public class Apple : Fruit
{
public object MakeAppleJuice() => null;
}
public class Orange : Fruit
{
public object MakeOrangeJuice() => null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment