Как преобразовать делегат R Function <T, R> (T t) в Func <T, R>? - PullRequest
6 голосов
/ 23 февраля 2012

У меня есть устаревший код, который определил следующий помощник

public delegate R Function<T, R>(T t);

Но я хочу поставить Func<T,TResult>

попытки приведения не скомпилированы

Невозможно преобразовать тип 'System.Func<T,TResult>' в 'Rhino.Mocks.Function<T,TResult>'

Есть ли способ, который не только компилирует, но и функционирует во время выполнения?

Ответы [ 3 ]

9 голосов
/ 23 февраля 2012

Джаред и Фог оба правы. Третий способ сделать то же самое, просто для округления, это:

Func<int, string> func = i => i.ToString();
Function<int, string> function = func.Invoke;

То есть новый делегат является делегатом метода вызова первого делегата , который имеет правильную подпись.

То, что нужно сделать, это досадно до крайности. Если бы мы сегодня проектировали среду выполнения с нуля, зная то, что мы теперь знаем о том, как люди используют типы делегатов, я думаю, вполне вероятно, что будет один встроенный тип делегата для каждой сигнатуры (так же, как и один типа "одномерный массив целых чисел"), или что среди типов делегатов будет "структурная идентичность". В следующий раз, когда вы создадите систему типов для виртуальной машины, помните об этом.

9 голосов
/ 23 февраля 2012

Проблема в том, что вы пытаетесь объединить два разных типа делегатов: Func<T, TResult> и Function<T, TResult>. Несмотря на то, что они имеют одну и ту же сигнатуру, они являются разными и, следовательно, несовместимыми типами.

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

Func<T, TResult> func = ...;
TheMethod(x => func(x));
8 голосов
/ 23 февраля 2012

Вы можете создать лямбду, как предлагает JaredPar, или передать одну в конструктор другой:

Func<int, string> f1 = i => i.ToString();
Function<int, string> f2 = new Function<int, string>(f1);
...