2017-01-03 3 views
0

Я пытаюсь использовать метод Convert как для функций, так и для действий, поэтому я могу избежать написания дублирующих методов, принимающих делегатов типа Func. Преобразовать метод исходит из Convert Action<T> to Action<object>Динамически конвертировать Func в соответствующее действие

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var program = new Program(); 
     var mi = program.GetType().GetMethod("Function", BindingFlags.Instance | BindingFlags.Public); 
     // Can be any version of Func 
     var funcType = typeof(Func<int, int>); 
     // Create action delegate somehow instead 
     var del = mi.CreateDelegate(funcType, null); 
     // Or dynamically convert the Func to a corresponding Action type (in this case Action<int>) 
    } 

    // Or find a way to pass it in as a parameter here 
    public Action<object> Convert<T>(Action<T> action) 
    { 
     return o => action((T)o); 
    } 

    public int Function(int five) 
    { 
     return five; 
    } 
} 
+0

Что не так с кодом? Не работает ли это так, как вы ожидаете? – dasblinkenlight

+0

Действие не имеет типа возврата –

+0

Нет ничего плохого в моем коде, он написан для улучшения понимания. Я просто хочу преобразовать переменную Func в соответствующую переменную Action динамически. – Martin

ответ

0

Я думаю, что вы ищете что-то вроде этого:

public static Action<T1> IgnoreResult<T1,T2>(Func<T1,T2> func) 
{ 
    return x => func(x); 
} 

Но для всех вариантов Func<T1,T2....>

Я думаю, что это будет работать:

public static Action<TR> IgnoreResult<TR>(Delegate f) 
{ 
    return x => f.DynamicInvoke(x); 
} 

С использованием:

var action = IgnoreResult<int>(new Func<int,int>(program.Function)); 
action(5); 

Вы не сможете получить его, чтобы вывести параметры и тип возвращаемого значения без копирования и вставки первый пример для всех вариантов Action<T1...> и Func<T1,T2...>.

+0

1. Решение. Как я уже упоминал в своем вопросе, моя цель состоит в том, чтобы иметь только один метод, который можно вызвать как для Action, так и для Func, который приводит нас к 2. Решение. Вы создаете делегата, который вызывает DynamicInvoke, который в 30 раз медленнее чем вызов напрямую. – Martin

+0

Правильно, так что вы хотите получить лучшее из обоих миров =) Это можно сделать, но все равно, я вернусь к вам – Stuart

+0

Я должен сказать вам, вы не можете использовать динамические ключевые слова или деревья выражений. Unity не поддерживает динамические деревья и деревья выражений поддерживаются только в версии 5.5.0 и выше, и LambdaExpression.Compile имеет настолько плохую производительность, что вам придется вызвать делегат миллионы раз, чтобы вернуть стоимость инициализации. – Martin

Смежные вопросы