Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Covariance and Contraviarance
namespace VarianceExample
class Program
static void Main(string[] args)
ISkinned<Fruit> skinnedFruit = null;
ISkinned<Banana> banana = null;
ICovariantSkinned<Fruit> covariantSkinnedFruit = null;
ICovariantSkinned<Banana> covariantBanana = null;
IContravariantSkinned<Fruit> contravariantSkinnedFruit = null;
IContravariantSkinned<Banana> contravariantBanana = null;
// Peel(bananaFruit); // cannot convert from 'ISkinned<Banana>' to 'ISkinned<Fruit>'
// PeelBanana(skinnedFruit); // cannot convert from 'ISkinned<Fruit>' to 'ISkinned<Banana>'
PeelCovariant(covariantBanana); // ok, since 'in T' generic type specified
PeelBananaContravariant(contravariantSkinnedFruit); // ok, since 'out T' generic type specified
static void Peel(ISkinned<Fruit> param) { }
static void PeelBanana(ISkinned<Banana> param) { }
static void PeelCovariant(ICovariantSkinned<Fruit> param) { }
static void PeelBananaContravariant(IContravariantSkinned<Banana> param) { }
class Fruit { }
class Banana : Fruit { }
interface ISkinned<T> { }
interface ICovariantSkinned<out T>
T Get();
// void Set(T outParam); // Invalid variance: The type parameter 'T' must be contravariantly valid on 'ICovariantSkinned<T>.Set(T)'. 'T' is covariant.
interface IContravariantSkinned<in T>
// T GetT(); // Invalid variance: The type parameter 'T' must be covariantly valid on 'IContravariantSkinned<T>.GetT()'. 'T' is contravariant.
void Set(T inParam);
// Based on
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment