Вы не необходимо сделать что-нибудь особенное.
Func<in T, out TResult>
является contravariant на T
- его входной параметр, и каждый тип наследует от object
, что означает, что вы можете просто броситьFunc<object, Task>
к Func<T, Task>
для любого ссылочного типаT
- передать его как есть, и она будет просто работать ,
Example
Теперь, это не будет работать для типов значений, поскольку те требуют распаковки заранее.
Так что, если ваш T
является типом значения, вам придется его обернуть в другом делегате, который выполнит литье.
Один простой способ будет определить метод обертку:
private static Func<T, TResult> CastFunc<T, TResult>(Func<object, TResult> fn)
=> param => fn(param);
Затем создать делегат посредством отражения:
var result = (Func<int, Task>)typeof(WrapperClass)
.GetMethod(nameof(CastFunc), BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(typeof(int), typeof(Task)).Invoke(null, new object[] { fn });
Дох. Я полностью пропустил это. –