Тип условного выражения не может быть определен (Func) - PullRequest
19 голосов
/ 10 июня 2011

При назначении метода для Func -типа я получаю ошибку компиляции Type of conditional expression cannot be determined because there is no implicit conversion between 'method group' and 'method group'.

Это происходит только с оператором ? :. Код:

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;
    }
}

Я нашел некоторую информацию о ко-и контравариантности, но я не понимаю, как это относится к ситуации выше. Почему это не работает?

Ответы [ 3 ]

29 голосов
/ 10 июня 2011

Вам необходимо явно указать сигнатуру хотя бы одной группы методов.Однако после этого компилятор позволит вам объявить action как локально неявно типизированный:

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

Причина, по которой это происходит, заключается в том, что возвращаемый тип operator ?: не определяется наВы пытаетесь присвоить его, но на основе типов двух выражений.Если типы одинаковы или между ними существует неявное преобразование, компилятор успешно выводит тип возвращаемого значения;в противном случае он жалуется на отсутствие конверсии.

6 голосов
/ 10 июня 2011

Когда вы непосредственно назначаете функцию делегату, компилятор преобразует функцию в требуемый тип делегата, если он соответствует подписи.

Однако, когда вы используете оператор?: Для компилятора вы не назначаете делегату напрямую, поэтому он не знает, какой тип использовать для One и Two, и поэтому считает, что два типа, используемые в операторе?: не совпадают.

Единственное исправление делает явное преобразование:

Func<int, string> action = which ? new Func<int, string>(One) : new Func<int, string>(Two);
2 голосов
/ 09 августа 2013

решение Джона работает

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

Другой альтернативой является создание нового анонимного делегата самостоятельно. Это семантически немного отличается, но я думаю, что это тоже может быть полезно.

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

Я нахожу это немного более элегантным, но не таким коротким ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...