开发者

Type of conditional expression cannot be determined (Func)

开发者 https://www.devze.com 2023-03-12 14:05 出处:网络
When assigning a method to a Func-type, I get the compi开发者_运维技巧lation error Type of conditional expression cannot be determined because there is no implicit conversion between \'method group\'

When assigning a method to a Func-type, I get the compi开发者_运维技巧lation error Type of conditional expression cannot be determined because there is no implicit conversion between 'method group' and 'method group'.

This only happens with the ? : operator. The code:

public class Test
{
    public static string One(int value)
    {
        value += 1;
        return value.ToString();
    }
    public static string Two(int value)
    {
        value += 2;
        return value.ToString();
    }
    public void Testing(bool which)
    {
        // This works
        Func<int, string> actionWorks;
        if (which) actionWorks = One; else actionWorks = Two;

        // Compilation error on the part "One : Two"
        Func<int, string> action = which ? One : Two;
    }
}

I found some information about co- and contravariance, but I don't see how that applies to the situation above. Why doesn't this work?


You need to explicitly provide the signature of at least one method group. However, after doing it the compiler will allow you to declare action as an implicitly-typed local:

var action = which ? (Func<int, string>)One : Two;

The reason this happens is that the return type of operator ?: is not deduced based on what you are trying to assign it to, but based on the types of the two expressions. If the types are the same or there is an implicit conversion between them, the compiler deduces the return type successfully; otherwise, it complains that there is no conversion.


When you directly assign a function to a delegate, the compiler will convert the function to the required delegate type if it matches the signature.

However, when you're using the ?: operator, as far as the compiler is concerned you're not directly assigning to a delegate, so it doesn't know what type to use for One and Two, and so it thinks the two types used in the ?: operator don't match.

The only fix is making the conversion explicit:

Func<int, string> action = which ? new Func<int, string>(One) : new Func<int, string>(Two);


Jon's solution works

var action = which ? (Func<int, string>)One : Two;

Another alternative is to create a new anonymous delegate yourself. This is semantically lil' different but I think this can be useful too.

Func<int, string> action = x => which ? One(x) : Two(x);

I find this lil' more elegant, though not as short..

0

精彩评论

暂无评论...
验证码 换一张
取 消