Search code examples
c#.netcovariancecontravariance

Covariance and Contravariance Confusion


I am confused on how contravariant/covariance works with C#. I have the following pseudo code

public static void Main()
{
    Action<string> action = e => Console.WriteLine(e);
    Execute(action);
}

private static void Execute(Action<object> action)
{
    action("hello world");
}

which throws

CS1502: The best overloaded method match for [...] has some invalid arguments

and I am not exactly sure why. also, what would be the correct way to do this?

In my real scenario I have a base interface I use instead of object passing in concrete instances.

Thanks!


Solution

  • Action<in T> is contravariant, meaning you can pass "bigger" types into the method. Because string is a smaller (more specific, or derived) than object, you get a compile time error. If you reversed your example, and created an Action<object> instead of Action<string>, your method would compile:

    public static void Main()
    {
        Action<object> action = e => Console.WriteLine(e);
        Execute(action);
    }
    
    private static void Execute(Action<string> action)
    {
        action("hello world");
    }