Variance (in/out) with interfaces & delegates
Understand C# variance: out for producers (covariance) and in for consumers (contravariance) on interfaces and delegates.
Variance overview
Variance lets generic interfaces/delegates work with inheritance.
- out = covariance (producer)
- in = contravariance (consumer)
- Safe when the API only produces or only consumes T
Covariance demo
IEnumerable<out T> is covariant: a sequence of cats can be used where a sequence of animals is expected.
using System;
using System.Collections.Generic;
public class Animal { public virtual string Name() { return "animal"; } }
public class Cat : Animal { public override string Name() { return "cat"; } }
public class Program
{
static void PrintAll(IEnumerable<Animal> animals)
{
foreach (Animal a in animals)
{
Console.WriteLine(a.Name());
}
}
public static void Main(string[] args)
{
List<Cat> cats = new List<Cat>();
cats.Add(new Cat());
// IEnumerable<Cat> -> IEnumerable<Animal> is allowed (out T)
PrintAll(cats);
}
}
All lessons in this course
- Generic methods/types; constraints
- Variance (in/out) with interfaces & delegates
- Nullable reference types (awareness) & annotations (C# 6 patterns)