0Pricing
C# Academy · Lesson

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

  1. Generic methods/types; constraints
  2. Variance (in/out) with interfaces & delegates
  3. Nullable reference types (awareness) & annotations (C# 6 patterns)
← Back to C# Academy