Невозможно определить универсальный тип с дополнительными параметрами - PullRequest
7 голосов
/ 28 марта 2012

Принимая во внимание следующую сигнатуру метода, почему при явном названии параметра компилятор не может автоматически определить тип?Visual Studio 2010 с пакетом обновления 1 (SP1) может выводить тип и не отображает предупреждений или ошибок.

IEnumerable<T> ExecuteCommand<T>(
    string commandText,
    string connectionName = null,
    Func<IDataRecord, T> converter = null) { ... }

static SomeClass Create(IDataRecord record) { return new SomeClass(); }

void CannotInferType() {
    var a = ExecuteCommand(
        "SELECT blah",
        "connection",
        converter: Test.Create);
}

void CanInferType() {
    var a = ExecuteCommand(
        "SELECT blah",
        "connection",
        Test.Create);
}

Вызывая его, как описано в CannotInferType, и при попытке его компиляции компилятор выдает error CS0411: The type arguments for method 'Test.ExecuteCommand<T>(string, string, System.Func<System.Data.IDataRecord,T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly., тогда как вызывая его какописанный в CanInferType работает должным образом.

Как указано выше, сама Visual Studio не сообщает о проблемах, и для переменной a intellisense показывает IEnumerable<SomeClass>, как и ожидалось, но по какой-то причине она не компилируется.

1 Ответ

7 голосов
/ 28 марта 2012

Это была ошибка в компиляторе C # 4.Это было исправлено в компиляторе C # 5.

Я подозреваю, что это не необязательный параметр, который вызывает проблему - это именованный аргумент.Попробуйте удалить значения по умолчанию для ваших параметров, и я подозреваю, что у вас все еще будет та же проблема.(Стоит провести различие между необязательными параметрами и именованными аргументами - это две отдельные функции. Они часто используются вместе, но, конечно, не обязательно.)

К такому выводу я пришел, когда отправилЭрик и Мэдс сообщают об этом ошибке:

using System;

class Test
{
    static void Foo<T>(Func<T> func) {}

    static void Main()
    {
        // Works fine
        Foo(() => "hello");

        // Type inference fails
        Foo(func: () => "hello");
    }
}

К счастью, теперь работает в бета-компиляторе C # 5.

...