Действие как Func в С#

У меня есть параметрический метод, который принимает Func как аргумент

SomeType SomeMethod<T>( Func<T, T> f ) {...}

Я хотел бы передать Action, не перегружая метод. Но это касается проблемы, как вы представляете и Action как Func? Я попробовал

Func<void, void>

но его недействительно.

Ответ 1

Вы можете создать метод расширения для переноса действия и возврата фиктивного значения:

public static class ActionExtensions
{
    public static Func<T, T> ToFunc<T>(this Action<T> act)
    {
        return a => { act(a); return default(T) /*or a*/; };
    }
}

Action<?> act = ...;
SomeMethod(act.ToFunc());

Возможно, будет проще, если вы создадите свой собственный тип Unit вместо использования object и вернете null.

Ответ 2

.NET Fiddle

То, что вы ищете, - это "выражение лямбда" msdn.

Оператор lambda - это когда вы завертываете свое выражение (правая сторона) в фигурные скобки {}. Это позволяет использовать более 1 оператора. Для вашего конкретного примера вы можете сделать это:

void Main()
{
    Func<bool,bool> f = i => {SomeAction();return true;};
    Console.WriteLine(SomeMethod(f));
}

public T SomeMethod<T>( Func<T, T> f ) 
{
    return f(default(T));
}

public void SomeAction()
{
    Console.WriteLine("called");
}

Выход

called
True

Ответ 3

Вы не можете превратить Action в Func. Но вы можете обернуть вызов Action в Func. Например, что-то вроде:

Action a = new Action<Foo>(f => { whatever });

Foo myFoo = ...;
Foo result = SomeMethod(new Func<Foo, Foo>(f => { a(myFoo); return myFoo; }));

(На данный момент у меня нет Visual Studio, но я думаю, что вы поняли эту идею.)