Difference between Covariance & Contra-variance

前端 未结 5 1497
小鲜肉
小鲜肉 2020-11-22 10:20

I am having trouble understanding the difference between covariance and contravariance.

5条回答
  •  -上瘾入骨i
    2020-11-22 10:44

    It's probably easiest to give examples - that's certainly how I remember them.

    Covariance

    Canonical examples: IEnumerable, Func

    You can convert from IEnumerable to IEnumerable, or Func to Func. Values only come out from these objects.

    It works because if you're only taking values out of the API, and it's going to return something specific (like string), you can treat that returned value as a more general type (like object).

    Contravariance

    Canonical examples: IComparer, Action

    You can convert from IComparer to IComparer, or Action to Action; values only go into these objects.

    This time it works because if the API is expecting something general (like object) you can give it something more specific (like string).

    More generally

    If you have an interface IFoo it can be covariant in T (i.e. declare it as IFoo if T is only used in an output position (e.g. a return type) within the interface. It can be contravariant in T (i.e. IFoo) if T is only used in an input position (e.g. a parameter type).

    It gets potentially confusing because "output position" isn't quite as simple as it sounds - a parameter of type Action is still only using T in an output position - the contravariance of Action turns it round, if you see what I mean. It's an "output" in that the values can pass from the implementation of the method towards the caller's code, just like a return value can. Usually this sort of thing doesn't come up, fortunately :)

    提交回复
    热议问题