質問

The following sums up my understanding of variance in C#. I'd appreciate if you can tell me what I'm getting wrong, cuz I read the article on Exact rules for variance validity By Eric Lippert, and I couldn't make sense of most of it.

Variance is the idea that a transformation (or projection as Eric Lippert puts it ) of a type to another type can preserve assignment compatibility (covariance), or reverse it (contravariance), or neither preserve it or reverse it (invariance). That is; if I is a covariant transformation in T, where T is a set of types, then for any T1 and T2 types in T, if T1 is Assignable to T2, then I<T1> is assignable to I<T2>. If I was contravariant, the result would be reverted. And if I was invariant, then neither I<T1> is assignable to I<T2> nor the opposite.

Now what does it mean for a type to be covariant or contravariant? Isn't variance a property of a projection-of-types and not a property of types themselves.

What does it mean that a generic type I<out T, in U> is covariant on T and contravariant on U?

Also, What does contravariant validity reverses the direction of variant validity and Covariant validity reverses the direction of variant validity mean?

役に立ちましたか?

解決

Now what does it mean for a type to be covariant or contravariant? Isn't variance a property of a projection-of-types and not a property of types themselves?

Yes, you are spot on. Well, you are almost spot on. Variance is a property of a projection of types with respect to a given relation on types.

Consider these statements:

  • The projection which maps from reference type T to type IEnumerable<T> preserves the direction of the assignment compatibility relation, and therefore that projection is covariant.

  • The projection from T to IEnumerable<T> is covariant in T.

  • IEnumerable<T> is covariant in T.

  • IEnumerable<T> is covariant.

We say the fourth one; we mean the first one. We assume that by "IEnumerable<T> is covariant" that it is clear from the context what the projection is (from T to IEnumerable<T>) and what the preserved relation is (assignment compatibility). It is just easier to say it that way.

In the article you mentioned I am at the beginning even sloppier than this; I use "covariant" basically to mean "can be involved in some way in a covariant conversion". However, the definitions of "covariantly valid" and so on are precise. If calling it "covariantly valid" makes it hard to understand, call it something else:

A type X is said to be a Frobby type if it is a pointer, or non-generic, or an array with Frobby element type, or generic type where every "in" type argument is Blobby, every "out" type argument is Frobby, and every other type argument is both Frobby and Blobby. It is said to be Blobby if it is a pointer, or non-generic, or an array with Blobby element type, or a generic type where every "in" type argument is Frobby, every "out" type argument is Blobby, and every other type argument is both Frobby and Blobby.

There, we didn't use the words "covariant" or "contravariant" at all, and we have a precise definition of both Frobby and Blobby.

What does it mean that a generic type I<out T, in U> is covariant on T and contravariant on U?

Again, this is just a short form. The first part means that for any fixed U, the projection from reference type T to I<T, U> is a projection which preserves the direction of assignment compatibility. If X is assignment compatible with Y and Z is any type, then I<X, Z> is assignment compatible with I<Y, Z>.

Similarly for the contravariant part, except now T is fixed, and the projection reverses the direction of the relation.

Also, What does "contravariant validity reverses the direction of variant validity" mean?

I meant that if you read the rules for covariant validity and compare them to the rules for contravariant validity, you notice that the rules are basically the same, just with a bunch of the rules "turned backwards". That's why we call it *contra*variance.

I have over a dozen articles on my blog about variance; you might want to read them starting at the beginning if this subject interests you.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top