In-depth understanding of covariant and contravariant interfaces in C#
Covariance and contravariance are concepts in object-oriented programming that define how references are used with different types. In C#, you can use the <out T>
and <in T>
syntax to mark an interface as covariant or contravariant respectively.
Covariance
In C#, covariance allows interface references to be treated as references to higher types in the hierarchy. For example, the interface IBibble<out T>
can be assigned an instance reference of IBibble<Descendant>
, as long as the Descendant
class inherits from the T
type. This means that anything that can be performed on IBibble<T>
can also be performed on IBibble<Descendant>
.
Inverter
In C#, contravariance allows interface references to be treated as references to lower types in the hierarchy. For example, the interface IBibble<in T>
can be assigned an instance reference of IBibble<Base>
, as long as the Base
type inherits from the T
type. This means that any object that can be assigned to IBibble<Base>
can also be assigned to IBibble<Descendant>
.
Uses and Applications
Covariance is useful when working with collections of objects that share a common base type. By using covariant interfaces, we ensure that operations performed on the base type also apply to all derived types.
Contravariance is useful when dealing with factories or delegates that accept parameters of different types. By using a contravariant interface, we ensure that any object that can be assigned to a base type can also be used as a parameter of a factory or delegate.
Example
Consider the following code snippet:
<code class="language-csharp">namespace SO2719954 { class Base { } class Descendant : Base { } interface IBibbleOut<out T> { } interface IBibbleIn<in T> { } class Program { static void Main(string[] args) { // 协变示例 IBibbleOut<Base> b = GetOutDescendant(); // IBibbleOut<Descendant> 赋值 // 逆变示例 IBibbleIn<Descendant> d = GetInBase(); // IBibbleIn<Base> 赋值 } static IBibbleOut<Descendant> GetOutDescendant() { return null; } static IBibbleIn<Base> GetInBase() { return null; } } }</code>
In this example, interface IBibbleOut<out T>
is covariant, allowing b
to reference Descendant
objects; interface IBibbleIn<in T>
is contravariant, allowing d
to reference Base
objects.
The above is the detailed content of How Do Covariance and Contravariance Enhance Interface Usage in C#?. For more information, please follow other related articles on the PHP Chinese website!