Skip to content

Latest commit

 

History

History
65 lines (33 loc) · 3.5 KB

ii.9.7-validity-of-member-signatures.md

File metadata and controls

65 lines (33 loc) · 3.5 KB

II.9.7 Validity of member signatures

To achieve type safety, it is necessary to impose additional requirements on the well-formedness of signatures of members of covariant and contravariant generic types.

This block contains only informative text.

  • Covariant parameters can only appear in "producer," "reader," or "getter" positions in the type definition; i.e., in

    • result types of methods

    • inherited interfaces

  • Contravariant parameters can only appear in "consumer," "writer," or "setter" positions in the type definition; i.e., in

    • argument types of methods
  • NonVariant parameters can appear anywhere.

End informative text.

We now define formally what it means for a co/contravariant generic type definition to be valid.

Generic type definition: A generic type definition G<var1 T1, …, varn Tn> is valid if G is an interface or delegate type, and each of the following holds, given S = <var1 T1, …, varn Tn>, where varn is +, -, or nothing:

  • Every instance method and virtual method declaration is valid with respect to S

  • Every inherited interface declaration is valid with respect to S

  • There are no restrictions on static members, instance constructors, or on the type's own generic parameter constraints.

Given the annotated generic parameters S = <var1 T1, …, varn Tn>, we define what it means for various components of the type definition to be valid with respect to S. We define a negation operation on annotations, written -S, to mean "flip negatives to positives, and positives to negatives". Think of

  • "valid with respect to S" as "behaves covariantly"

  • "valid with respect to ¬S" as "behaves contravariantly"

  • "valid with respect to S and to ¬S" as "behaves non-variantly".

Note that the last of these has the effect of prohibiting covariant and contravariant parameters from a type; i.e., all generic parameters appearing shall be non-variant.

Methods. A method signature t meth(t1, …, tn) is valid with respect to S if

  • its result type signature t is valid with respect to S; and

  • each argument type signature ti is valid with respect to ¬S.

  • each method generic parameter constraint type tj is valid with respect to ¬S.

[Note: In other words, the result behaves covariantly and the arguments behave contravariantly. Constraints on generic parameters also behave contravariantly. end note]

Type signatures. A type signature t is valid with respect to S if it is

  • a non-generic type (e.g., an ordinary class or value type)

  • a generic parameter Ti for which vari is + or none (i.e., it is a generic parameter that is marked covariant or non-variant)

  • an array type u[] and u is valid with respect to S; i.e., array types behave covariantly

  • a closed generic type G<t1,…,tn> for which each

    • ti is valid with respect to S, if the i'th parameter of G is declared covariant

    • ti is valid with respect to ¬S, if the i'th parameter of G is declared contravariant

    • ti is valid with respect to S and with respect to ¬S, if the i'th parameter of G is declared non-variant.