Можно ли использовать динамические функции делегата (которые принимают
переменная длина списка параметров с неизвестными типами), но принудительно
функция делегата для возврата определенного типа? С нединамическим делегатом
функции, которые вы устанавливаете тип возврата, но также должны установить количество
параметры и их типы.
Вы не «заставляете» функцию возвращать что-либо. Функция возвращает что-то или не возвращает что-то. Функция «заставляет» вас что-то принимать :-) (или игнорировать это)
Вы можете вызвать динамический делегат через DynamicInvoke
, а затем привести возвращаемое значение к тому, что, как вы знаете, возвращает ваш делегат (или вы сохраняете его как object
). Я говорю «то, что, как вы знаете, возвращает ваш делегат», но реальность немного сложнее: для типов значений вы должны привести возвращаемое значение точно к типу, используемому в качестве возвращаемого значения, или вы получите InvalidCastException
. Для ссылочных типов вы можете использовать интерфейс или базовый класс возвращаемого объекта (за некоторыми исключениями для типов Nullable)
Насколько медленнее использование DynamicInvoke, чем использование нединамического делегата?
Я протестировал метод void Do()
(самый простой из возможных, без упаковки параметров), и разница во времени была незначительной. Скажем, 400x :-) На http://ideone.com/f34cj это между 70x и 150x.
Нужно ли объявлять 'new Func (Math.Pow)' для передачи функции power, или есть способ просто передать Math.Pow (и неявно передать тип и параметры возврата)?
Создание нового делегата Func
/ Action
- правильный путь.
В общем, правильное решение - это не то, что вы делаете. Правильное решение - это делать, как это делает LINQ. Например:
int pow = 2;
Func<int, int> myFunc = p => (int)Math.Pow(p, pow);
var listOfNumbers = Enumerable.Range(1, 100);
var result = listOfNumbers.Sum(p => myFunc(p));
Теперь у вас есть делегат (myFunc
), который берет число и возвращает квадрат этого числа (и обратите внимание, что через «замыкания» он закрывается около pow
) (если вы не знаете, что такое замыкание попробуйте вставить это слово в Google с помощью функции лямбда-слов). Список чисел в виде IEnumerable<int>
, и вы делаете сумму этих чисел, «преобразованную» в myFunc
.