Преобразование между Func с разными # типами аргументов - PullRequest
1 голос
/ 02 апреля 2011

Существуют ли встроенные методы для преобразования между различными типами делегатов Func?То есть предположим, что вам нужен Func, но у вас есть Func (и у вас есть значение, которое должно быть передано для параметра T).Например:

static TREsult Foo<TResult>(Func<TResult> f)
{
   // ...
   TResult result = f();
   // ...
   return result;
}

static int MyFunc(int i)
{
    return i;
}

void CallFoo()
{
    Func<int> func = ConvertFunc(MyFunc, 1); // Does this family of methods exist?
    int j = Foo(func);
}

Я написал свое собственное, например:

    static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
    {
        return () => f1(t);
    }

    static Func<TResult> ConvertFunc<T1, T2, TResult>(Func<T1, T2, TResult> f2, T1 t1, T2 t2)
    {
        return () => f2(t1, t2);
    }

    // etc.

Но мне интересно, существует ли такое семейство методов (или даже если естьэто лучший способ сделать это)но тип возврата тот же), затем код котельной плиты.

Все мнения приветствуются!Спасибо.

1 Ответ

3 голосов
/ 02 апреля 2011
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
    return () => f1(t);
}

Этот вид кода для меня выглядит немного опасно - не то, чтобы само по себе что-то не так, но нужно быть осторожным .Вы используете замыкание для встраивания входной переменной в функцию.Но это может привести к трудным ошибкам, так как, если переменная изменится между преобразованием Func и его запуском, результат будет другим.

Мне просто любопытно, какая будет польза.Вы пытаетесь скрыть входной параметр от потребителя функции?Пока переменная является локальной, переданной ей, все будет в порядке.

С точки зрения решения ее не будет, поскольку .NET создал 16 различных универсальных Func<> точно по той же причине.

Возможно, вы можете использовать отражение для реализации решения, но вы будете платить штраф за вызов функций.MethodInfo.GetGenericArguments() даст вам типы, и вы сможете использовать MethodInfo.MakeGenericMethod() для создания новых.


Обновление

Просто чтобы проиллюстрировать мою точку зрения:

    static int Double(int number)
    {
        return number * 2;
    }

    static void Main(string[] args)
    {

        int i = 2;
        Func<int> f = () => Double(i);
        i = 3;
        Console.WriteLine(f()); // prints 6 and not 4

    }
...