Параметр общего типа и перегрузка метода Nullable - PullRequest
9 голосов
/ 28 апреля 2011

ПриветУ меня есть этот код, используя generic и nullable:

// The first one is for class
public static TResult With<TInput, TResult>(this TInput o, 
          Func<TInput, TResult> evaluator)
    where TResult : class
    where TInput : class

// The second one is for struct (Nullable)
public static TResult With<TInput, TResult>(this Nullable<TInput> o, 
          Func<TInput, TResult> evaluator)
    where TResult : class
    where TInput : struct

Обратите внимание на ограничение TInput, один класс, другой структура.Затем я использую их в:

string s;
int? i;

// ...

s.With(o => "");
i.With(o => ""); // Ambiguos method

Это вызывает ошибку Ambiguos.Но у меня также есть другая пара:

public static TResult Return<TInput, TResult>(this TInput o,
          Func<TInput, TResult> evaluator, TResult failureValue)
    where TInput : class

public static TResult Return<TInput, TResult>(this Nullable<TInput> o,
          Func<TInput, TResult> evaluator, TResult failureValue)
    where TInput : struct

Эта успешно компилируется

string s;
int? i;

// ...

s.Return(o => 1, 0);
i.Return(o => i + 1, 0);

Я не знаю, почему это происходит.Первый выглядит нормально, но компилирует ошибку.Второй («Return») должен быть ошибочным, если первый есть, но успешно компилируется.Я что-то пропустил?

1 Ответ

10 голосов
/ 28 апреля 2011

Ограничения в общем методе не учитываются, пока выбирает перегрузку - они проверяются после была выбрана перегрузка.

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

У меня есть сообщение в блоге по этому вопросу, которое может помочь понять его дальше.

Кроме того, обратите внимание, что ваш второй примеримеет дополнительный аргумент, который способствует выводу типа, что и делает различие между ними.TResult выводится как int, что предотвращает допустимость первой перегрузки - преобразования (int? x) => x + 1 в Func<int?, int> нет, тогда как означает преобразования (int x) => x + 1 в Func<int, int>.

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