C# Covariance And Contravariance

C# Code Snippets Covariance And Contravariance
Share:

About

In this code snippet, we’ll take a look at covariance and contravariance in C#.

Covariance and contravariance enable implicit type conversion for arraysdelegates and generic interface type arguments.

Covariance allows for a more derived type to be used where a less derived type is expected. This can be done implicitly because a more derived type contains all the members of a less derived type.

Contravariance allows for a less derived type to be used where a more derived type is expected. This can be done because a less derived type will have all the members the more derived type has.

Let’s have a look at the code below to see an example of covariance and contravariance.

Code:

namespace CovarianceContravariance
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //To quote https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/covariance-contravariance/
            //"In C#, covariance and contravariance enable implicit reference conversion for array types, delegate types, and generic type arguments.
            //Covariance preserves assignment compatibility and contravariance reverses it."

            //Covariance is when a more derived type is assigned to a less derived one.
            Action<string> funcMyMethodString = MyMethod;
            Action<string> funcMyMethodObject = funcMyMethodString;


            //Contravariance is when a less derived type is assigned to a more derived one.
            Action<object> funcMyOtherMethod = MyOtherMethod;
            Action<string> funcMyOtherMethodString = funcMyOtherMethod;
        }

        static void MyOtherMethod(object input) 
        {
            //Do something...
        }

        static void MyMethod(string input)
        {
            //Do something...
        }



        //Generic type parameters in interfaces can be covariant(out keyword) or contravariant(in keyword).
        //Covariant interface methods can have a more derived return type than defined by the generic type parameters.
        //Contravariant interface methods can have less derived input parameter types than those defined by the generic parameters.
        interface MyCovariantInterface<out T>
        {
            //Methods can return type of T.
            T MyMethod();
            //Methods can't take type of T as an input parameter. 
            //void MyOtherMethod(T input); //Throws error if uncommented.
        }

        interface MYContravariantInterface<in T>
        {
            //Methods can take type of T as an input parameter.
            void MyMethod(T input);
            void DoSomething<U>() where U : T; //Type constraints can be specified if desired. I briefly covered constraints in this post: https://eecs.blog/c-generics/
            //Methods can't return type of T.
            //T MyOtherMethod(); //Throws error if uncommented.
        }
    }
}
Share:

Leave a Reply

Your email address will not be published. Required fields are marked *

The following GDPR rules must be read and accepted:
This form collects your name, email and content so that we can keep track of the comments placed on the website. For more info check our privacy policy where you will get more info on where, how and why we store your data.

Advertisment ad adsense adlogger