Last active
January 6, 2018 16:26
-
-
Save ignas-sakalauskas/a5bee482f4ea56e19f9db1bf72438ac4 to your computer and use it in GitHub Desktop.
Covariance and Contraviarance
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(skinnedFruit); | |
// Peel(bananaFruit); // cannot convert from 'ISkinned<Banana>' to 'ISkinned<Fruit>' | |
// PeelBanana(skinnedFruit); // cannot convert from 'ISkinned<Fruit>' to 'ISkinned<Banana>' | |
PeelBanana(banana); | |
PeelCovariant(covariantSkinnedFruit); | |
PeelCovariant(covariantBanana); // ok, since 'in T' generic type specified | |
PeelBananaContravariant(contravariantSkinnedFruit); // ok, since 'out T' generic type specified | |
PeelBananaContravariant(contravariantBanana); | |
} | |
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 https://stackoverflow.com/a/20660947/5540176 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment