问题 在C#中作为Func操作


我有一个参数方法,需要一个 Func 作为一个论点

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

我想传递一个 Action 无需重载方法。但是这就解决了这个问题,你如何代表和 Action 作为一个 Func?我试过了

Func<void, void>

但它无效。


1106
2018-05-30 17:40


起源

您 不能....... - Selman Genç
从来没有,Func不允许void返回类型(因为Action的代表存在)。您始终可以将Action包装为lambda(o)=> {ExecuteAction();返回true; } - Gusman
非常好的问题,也是一个在C#中没有令人满意的答案的问题。您遇到此问题: james-iry.blogspot.com/2009/07/void-vs-unit.html - pyon
@Gusman是的,这基本上就是我在做什么,但这让我写了一个不必要的回报,这就是我想要解决的问题。 - Cristian Garcia
如果不需要返回,为什么SomeMethod会期望一个Func?当然它正在使用该返回值。 - Kyle


答案:


您可以创建一个扩展方法来包装操作并返回一个虚拟值:

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。


11
2018-05-30 17:48



从未使用默认值,它做什么? - Cristian Garcia
@CristianGarcia - 它回归 null 对于引用类型,对于值类型为“零”。 - Lee
我收到此错误: Extension method must be defined in a non-generic static class - Cristian Garcia
@CristianGarcia - 您必须在静态类中定义扩展方法 - 请参阅更新。 - Lee
@CristianGarcia此外,结构体是不能设置为0的值类型。结构体的默认值是将其所有值属性设置为0并将其引用属性设置为null。 msdn.microsoft.com/en-us/library/aa664475(v=vs.71).aspx - Mister Epic


.NET Fiddle

你在寻找什么是“声明lambda” 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
2018-05-30 17:56





你不能转 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,但我认为你明白了。)


1
2018-05-30 17:47