bit
bit

Reputation: 509

How do I achieve implicit conversion of an argument to a parameter using a variant delegate?

I want to implicitly convert an argument to a parameter instead of explicitly converting the argument using a type cast. The argument is less derived than the parameter, so using a contravariant delegate I expected the argument to be implicitly converted to the parameter. However, the compiler still complains that I need to explicitly convert "object" to "string".

public static void Main()
{
DDoSomething<string> doSomething = DoSomething;

object obj = "text";

doSomething(obj);
}

public delegate void DDoSomething<in A>(A str);

public static void DoSomething(string str)
{

}

Upvotes: 0

Views: 469

Answers (1)

Johnathan Barclay
Johnathan Barclay

Reputation: 20354

You can't call a method that expects a string with an object, or more generally, you cannot use a base instance in place of a derived instance.

When you do this:

DDoSomething<string> doSomething = DoSomething;

doSomething is now effectively a method with this signature: void (string).

Contravariance applies to the delegate instance itself, not the arguments:

public static void Main()
{
    DDoSomething<object> doSomething = (object obj) => Console.WriteLine(obj);
    
    DDoSomething<string> doSomethinString = doSomething;
    // Using a DDoSomething<object> in place of DDoSomething<string> is legal because of "in"

    doSomethinString("text");
    // This is safe because string is used in place of object (derived in place of base)
}

public delegate void DDoSomething<in A>(A str);

Upvotes: 1

Related Questions