Generic Variance
From The Oxygene Language Wiki
This is a Language topic
Feel free to add your notes to this topic below.
Generic variance is the ability to assign a generic interface or delegate type to the same type with another parameter; it was introduced in the May 2009 Release (3.0.19), to for example, assign IEnumerable<String> to IEnumerable<Object>. The runtime has had a special flag for this already, which unfortunately isn't set on any interface or delegate in .NET 2.0 or 3.5, but 4.0 will offer this change in types where it makes sense. Generic variance has to be defined on the generic parameter type that supports them. There are two kinds of generic variance, covariance and contravariance. Covariance can be defined with the out keyword, contravariance with the in keyword.
type IMyInterface<out T> = interface property Value: T read; end; IMyOtherInterface<in T> = interface procedure Update(item: T); end;
For covariance, the generic parameter that has the out keyword can only be used in function results and read-only properties. For contravariance the generic parameter can be used in regular (non out or var) parameters in functions. Covariance types can be widened, contravariance types can be narrowed when assigning:
var lMy: IMyInterface<string>; lMyObj: IMyInterface<object>; lMyObj := lMy; // only valid from a subclass to a parent class var lMyOther: IMyOtherInterface<object>; lMyOtherStr: IMyOtherInterface<string>; lMyOtherStr := lOther; // only valid from a parent class to a sub class
Generic variance can only work when the types are both reference types, value types are not allowed.
Note: Mono support
Mono introduced support for generic variance on delegates & interfaces in 2010 and will be part of Mono 2.8. When targeting mono, avoid using generic variance, as it may cause exceptions.
See Also
Area: Oxygene Language
Compiler version: Oxygene 5
Language Glossary — Keywords — Types — FAQ — How To